SlideShare une entreprise Scribd logo
1  sur  70
Télécharger pour lire hors ligne
How to code
to code less
github.com/anton-novikau
Anton Novikau
Lead Android Developer @ Viber Media
Boilerplate Fighters!
Agenda
What is Annotation Processor?
How does it work?
Project structure
Create Annotation Processor
How to debug Processor’s code?
Demo time!
How to setup a goal?
Java Annotation Processors
Processing Rounds
TODO BUILD DONE
D
A C
B
E
F
Round 1
Processing Rounds
TODO BUILD DONE
Round 1
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 1
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 1
AA
FA
FB D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 1
AA
FA
FB
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 2
AA
FA
FB
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 2
AA
FA
FB
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 2
AA
FA
FB
AAA
D
A C
B
E
F
Processing Rounds
TODO BUILD DONE
Round 2
AAA
D
A C
B
E
F
AA
FA
FB
Processing Rounds
TODO BUILD DONE
Round 3
AAA
D
A C
B
E
F
AA
FA
FB
Processing Rounds
TODO BUILD DONE
Round 3
AAA
D
A C
B
E
F
AA
FA
FB
public class Person {
private String firstName;
private String lastName;
private Date birthday;
}
@Pojo
@Pojo
public class Person {
private String firstName;
private String lastName;
private Date birthday;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Date getBirthday() {
return birthday;
}
Where to get source data to generate code?
Before we start
Inheritance vs Composition
What should be a start point for our processor?
Inheritance
public class Contact implements Parcelable {
}
public static final Creator<Contact> CREATOR =
new Creator<Contact>() {
@Override
public Contact createFromParcel(Parcel source) {
return new Contact(source);
}
@Override
public Contact[] newArray(int size) {
return new Contact[size];
}
};
...
Inheritance
public class Contact implements Parcelable {
}
public class Contact implements Parcelable {
}
Inheritance
...
public Contact() {
}
Contact(Parcel source) {
...
}
...
public class Contact implements Parcelable {
}
Inheritance
...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
...
}
class Smart_Contact extends Contact {
// creator
// constructor
// methods from Parcelable
}
@SmartParcelable
public abstract class Contact implements Parcelable {
}
Inheritance
class Smart_Contact extends Contact {
// creator
// constructor
// methods from Parcelable
}
@SmartParcelable
public abstract class Contact implements Parcelable {
public static Contact create() {
return new Smart_Contact();
}
}
Inheritance
Composition
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
...
public void onMigrateImageClicked(View v) {
MainActivityPermissionsDispatcher
.migrateImageWithPermissionCheck(this);
}
@NeedsPermission(WRITE_EXTERNAL_STORAGE)
void migrateImage() {
...
}
}
Composition
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
...
public void onMigrateImageClicked(View v) {
MainActivityPermissionsDispatcher
.migrateImageWithPermissionCheck(this);
}
@NeedsPermission(WRITE_EXTERNAL_STORAGE)
void migrateImage() {
...
}
}
Composition
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
...
public void onMigrateImageClicked(View v) {
MainActivityPermissionsDispatcher
.migrateImageWithPermissionCheck(this);
}
@NeedsPermission(WRITE_EXTERNAL_STORAGE)
void migrateImage() {
...
}
}
Where to get source data to generate code?
What should be a start point for our processor?
Before we start
Inheritance vs Composition
Effort of using your generated code vs creating a boilerplate code
Cursor boilerplate
public class ContactEntity {
long id;
String name;
Uri photoUri;
}
Cursor boilerplate
ContactEntity contact = new ContactEntity();
contact.setId(c.getLong(0));
contact.setName(c.getString(1));
contact.setPhotoUri(Uri.parse(c.getString(2)));
Cursor c = db.query("contacts",
"_ID = ?",
new String[] {"_ID", "NAME", "PHOTO"},
new String[] { String.valueOf(id) },
null, null, null);
ContactEntity contact = new ContactEntity();
contact.setId(c.getLong(0));
contact.setName(c.getString(1));
String uri = c.getString(2);
if (uri != null) {
contact.setPhotoUri(Uri.parse(uri));
}
Cursor boilerplate
Cursor c = db.query("contacts",
"_ID = ?",
new String[] {"_ID", "NAME", "PHOTO"},
new String[] { String.valueOf(id) },
null, null, null);
Cursor boilerplate
ContentValues values = new ContentValues();
values.put("_ID", contact.getId());
values.put("NAME", contact.getName());
values.put("PHOTO", contact.getPhotoUri().toString());
db.update("contacts",
values,
"_ID = ?",
new String[] { String.valueOf(contact.getId()) });
ContentValues values = new ContentValues();
values.put("_ID", contact.getId());
values.put("NAME", contact.getName());
String photoUri = contact.getPhotoUri() != null
? contact.getPhotoUri().toString()
: null
values.put("PHOTO", photoUri);
Cursor boilerplate
db.update("contacts",
values,
"_ID = ?",
new String[] { String.valueOf(contact.getId()) });
Goal
public class ContactEntity {
long id;
String name;
Uri photoUri;
}
Goal
@Entity(table = "contacts")
public class ContactEntity {
@Column(name = "_ID")
@PrimaryKey
long id;
@Column(name = "NAME")
String name;
@Column(name = "PHOTO", adapter = UriTypeAdapter.class)
Uri photoUri;
}
Project Structure
Project
api
processors
application
API Module
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
compileOnly 'com.google.android:android:4.1.1.4'
}
API Module
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
compileOnly 'com.google.android:android:4.1.1.4'
}
API Module
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Entity {
String table();
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface Column {
String name();
Class<? extends TypeAdapter<?>> adapter();
}
API Module
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Entity {
String table();
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface Column {
String name();
Class<? extends TypeAdapter<?>> adapter();
}
Processors Module
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
implementation project(':api')
}
Processors Module
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
implementation project(':api')
}
Create Annotation Processor
@SupportedAnnotationTypes("roomie.api.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EntityHelperProcessor extends AbstractProcessor {
@Override
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
...
}
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
...
}
}
Create Annotation Processor
@SupportedAnnotationTypes("roomie.api.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EntityHelperProcessor extends AbstractProcessor {
@Override
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
...
}
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
...
}
}
Create Annotation Processor
@SupportedAnnotationTypes("roomie.api.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EntityHelperProcessor extends AbstractProcessor {
@Override
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
...
}
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
...
}
}
Create Annotation Processor
@SupportedAnnotationTypes("roomie.api.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EntityHelperProcessor extends AbstractProcessor {
@Override
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
...
}
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
...
}
}
Register Processor
Project
processors
src
main
resources
META-INF
services
Old Fashioned way
javax.annotation.processing.Processor
roomie.codegen.EntityHelperProcessor
...
Register Processor
Modern way
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
implementation project(':api')
implementation 'com.google.auto:auto-common:0.8'
compileOnly 'com.google.auto.service:auto-service:1.0-rc4'
}
Register Processor
Modern way
@AutoService(Processor.class)
@SupportedAnnotationTypes("roomie.api.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class EntityHelperProcessor extends AbstractProcessor {
...
}
Write a simple Class
package roomie.example;
public class DemoImpl extends Demo {
int counter;
public void print(String msg) {
System.out.println(msg);
}
}
Write a simple Class: raw text
JavaFileObject sourceFile =
filer.createSourceFile(qualifiedName, annotatedClass);
try (Writer writer = sourceFile.openWriter()) {
writer.append("package ");
writer.append(packageName).append(";nn");
writer.append("public class ").append(className);
writer.append(" extends ");
writer.append(annotatedClass.simpleName()).append(" {n");
writer.append(" int counter;nn");
writer.append(" public void print(String msg) {n");
writer.append(" System.out.println(msg);n");
writer.append(" }n");
writer.append("}n");
writer.flush();
}
Processors Module
apply plugin: 'java-library'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
implementation project(':api')
implementation 'com.squareup:javapoet:1.9.0'
implementation 'com.google.auto:auto-common:0.8'
compileOnly 'com.google.auto.service:auto-service:1.0-rc4'
}
JavaFile DemoImpl.java
TypeSpec class DemoImpl
MethodSpec void print()
FieldSpec int counter
ParameterSpec String msg
JavaPoet Java
=
Write a simple Class: JavaPoet
Define Class
TypeSpec.Builder classContent =
TypeSpec.classBuilder(className)
.addModifiers(Modifier.PUBLIC)
.superclass(annotatedClass);
Write a simple Class: JavaPoet
Define Method and Field
MethodSpec print =
MethodSpec.methodBuilder("print")
.addModifiers(Modifier.PUBLIC)
.addParameter(String.class, "msg")
.addStatement(“$L.out.println(msg)",
System.class)
.build();
FieldSpec counter =
FieldSpec.builder(int.class, "counter").build();
classContent.addMethod(print);
classContent.addField(counter);
Write a simple Class: JavaPoet
Write our Class to a File
JavaFile javaFile = JavaFile.builder(packageName,
classContent.build())
.indent(" ")
.build();
JavaFileObject sourceFile = filer.createSourceFile(
qualifiedName,
annotatedClass);
try (Writer writer = sourceFile.openWriter()) {
writer.write(javaFile.toString());
}
Don’t worry.
We’ve almost finished
Application Module
apply plugin: 'com.android.application'
android {
...
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
implementation project(':api')
annotationProcessor project(':codegen')
...
}
Application Module
apply plugin: 'com.android.application'
android {
...
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
implementation project(':api')
annotationProcessor project(':codegen')
...
}
Application Module
apply plugin: 'com.android.application'
android {
...
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
implementation project(':api')
annotationProcessor project(':codegen')
...
}
How to Debug?
How to Debug?
Setup Gradle Daemon
vim ~/.gradle/gradle.properties
org.gradle.daemon=true
org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,
server=y,suspend=n,address=5005
Start Daemon and Connect
./gradlew --stop
./gradlew --daemon
./gradlew clean :sample:compileDebugJavaWithJavac
Demo Time
Conclusion
Thank you!
Questions?
Useful Links
Hannes Dorfmann - Annotation Processing 101
Eugenio Marletti - Pushing the limits of Kotlin annotation processing
Demo App (aka Roomie) Source Code

Contenu connexe

Tendances

Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Fabio Collini
 
Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Antoine Sabot-Durand
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeFabio Collini
 
JUnit 5 — New Opportunities for Testing on the JVM
JUnit 5 — New Opportunities for Testing on the JVMJUnit 5 — New Opportunities for Testing on the JVM
JUnit 5 — New Opportunities for Testing on the JVMVMware Tanzu
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized projectFabio Collini
 
Level Up Your Android Build -Droidcon Berlin 2015
Level Up Your Android Build -Droidcon Berlin 2015Level Up Your Android Build -Droidcon Berlin 2015
Level Up Your Android Build -Droidcon Berlin 2015Friedger Müffke
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMFabio Collini
 
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019Sam Brannen
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzgKristijan Jurković
 
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...LogeekNightUkraine
 
Angular 5 presentation for beginners
Angular 5 presentation for beginnersAngular 5 presentation for beginners
Angular 5 presentation for beginnersImran Qasim
 
Angular interview questions
Angular interview questionsAngular interview questions
Angular interview questionsGoa App
 
JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019Sam Brannen
 
Java Graphics Programming
Java Graphics ProgrammingJava Graphics Programming
Java Graphics ProgrammingRiccardo Cardin
 
Angular Introduction By Surekha Gadkari
Angular Introduction By Surekha GadkariAngular Introduction By Surekha Gadkari
Angular Introduction By Surekha GadkariSurekha Gadkari
 
JUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVMJUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVMSam Brannen
 
Rich GUI Testing: Swing and JavaFX
Rich GUI Testing: Swing and JavaFXRich GUI Testing: Swing and JavaFX
Rich GUI Testing: Swing and JavaFXAlex Ruiz
 

Tendances (20)

Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015
 
Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014Introduction to cdi given at java one 2014
Introduction to cdi given at java one 2014
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
JUnit 5 — New Opportunities for Testing on the JVM
JUnit 5 — New Opportunities for Testing on the JVMJUnit 5 — New Opportunities for Testing on the JVM
JUnit 5 — New Opportunities for Testing on the JVM
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized project
 
Level Up Your Android Build -Droidcon Berlin 2015
Level Up Your Android Build -Droidcon Berlin 2015Level Up Your Android Build -Droidcon Berlin 2015
Level Up Your Android Build -Droidcon Berlin 2015
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
 
Mock test rad 2
Mock test rad 2Mock test rad 2
Mock test rad 2
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzg
 
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...
Pavlo Zhdanov "Java and Swift: How to Create Applications for Automotive Head...
 
Angular 5 presentation for beginners
Angular 5 presentation for beginnersAngular 5 presentation for beginners
Angular 5 presentation for beginners
 
Angular interview questions
Angular interview questionsAngular interview questions
Angular interview questions
 
JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019
 
Java Graphics Programming
Java Graphics ProgrammingJava Graphics Programming
Java Graphics Programming
 
Call
CallCall
Call
 
Angular Introduction By Surekha Gadkari
Angular Introduction By Surekha GadkariAngular Introduction By Surekha Gadkari
Angular Introduction By Surekha Gadkari
 
JUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVMJUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVM
 
Rich GUI Testing: Swing and JavaFX
Rich GUI Testing: Swing and JavaFXRich GUI Testing: Swing and JavaFX
Rich GUI Testing: Swing and JavaFX
 

Similaire à How to code to code less

Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows Azure
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows AzureDeveloping Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows Azure
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows AzureRainer Stropek
 
Saindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender androidSaindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender androidDaniel Baccin
 
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptxNew features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptxMuralidharan Deenathayalan
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.UA Mobile
 
Vaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIVaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIPeter Lehto
 
rssfeeds.classpathrssfeeds.project rssfeed .docx
rssfeeds.classpathrssfeeds.project  rssfeed  .docxrssfeeds.classpathrssfeeds.project  rssfeed  .docx
rssfeeds.classpathrssfeeds.project rssfeed .docxjoellemurphey
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
Android architecture
Android architecture Android architecture
Android architecture Trong-An Bui
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EEAlexis Hassler
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android JetpackAhmad Arif Faizin
 

Similaire à How to code to code less (20)

Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows Azure
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows AzureDeveloping Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows Azure
Developing Android and iOS Apps With C#, .NET, Xamarin, Mono, and Windows Azure
 
Saindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender androidSaindo da zona de conforto… resolvi aprender android
Saindo da zona de conforto… resolvi aprender android
 
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptxNew features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
 
Rcp by example
Rcp by exampleRcp by example
Rcp by example
 
Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.Refactoring Wunderlist. UA Mobile 2016.
Refactoring Wunderlist. UA Mobile 2016.
 
Vaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UIVaadin DevDay 2017 - DI your UI
Vaadin DevDay 2017 - DI your UI
 
rssfeeds.classpathrssfeeds.project rssfeed .docx
rssfeeds.classpathrssfeeds.project  rssfeed  .docxrssfeeds.classpathrssfeeds.project  rssfeed  .docx
rssfeeds.classpathrssfeeds.project rssfeed .docx
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
Android architecture
Android architecture Android architecture
Android architecture
 
Griffon Presentation
Griffon PresentationGriffon Presentation
Griffon Presentation
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EE
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android Jetpack
 

Dernier

"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 

Dernier (20)

"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 

How to code to code less