SlideShare a Scribd company logo
1 of 34
Download to read offline
How to build fast, clean and flexible
Android architecture
ofer@dapulse.com
Ofer Tour
The art or science of building
a unifying or coherent form
or structure.
Architecture
Intent
Our Goal Code
• Easy to iterate on
• Collaboration-friendly
• Separated concerns
• Easy to test
Why does Android
Suck at testing?
• Activities, Services, Broadcast Receivers,
Content Providers, Bundles, Intents
• Fragments, Views, Notifications, Resources
• Databases, IPC, Threads, Storage
• Thousands of APIs related to services and
specific hardware features of devices
• Support libraries and external third party libraries
Single responsibility
Open/close
Liskov substitution principle
Interface segregation principle
Dependency inversion principle
SOLID
Dependency Injection
What we can easily replace –
we can easily test
By declaring on which other components or abilities
our current component depends, we get:
• Decoupled code
• Better understanding of what this components
does, and what it needs
• Replaceable and extendible code
• Easy to mock and test
Watch out for static class and new
variable declarations
Dependency Injection
What we can easily replace –
we can easily test
public class RateUsManager {

public RateUsManager(Context context) {

this.context = context;
this.prefs = PreferenceManager.getDefaultShared
Preferences(app);
this.analytics = new Analytics(context);
}
public void showIfNeeded {
if (lots of code conditions depending on prefs) {
prefs.edit().putInt(RATE_US_SHOWN,
prefs.getInt(RATE_US_SHOWN,0) + 1);
analytics.report(“rate us shown”);
}
}
private void reportRate(int starts) {

NetworkManager.reportRate(starts);
}
}
Dependency
Injection
public class RateUsManager {

public RateUsManager(RateUsPrefrences ratePrefs,
NetworkModule networkManager,
AnalyticsHelper analytics) {

}
public void showIfNeeded {
if (ratePrefs.shouldShow()) {
ratePrefs.increaseShowCount();
analytics.report(“rate us shown”);
}
}
private void reportRate(int starts) {

networkManager.reportRate(starts);
}
}
Dependency
Injection
Independent
Business Logic
We want to separate our business logic code
from the framework independent code:
• It will make our code more reusable
• It will make our code better structured and easier
to maintain
• Testing will become much clearer
Repositories
+ Converters
Interactors
Presenters
View Interface
Android, Web,
3rd Parties, DB
VIPER
View
Interactor
Presenter
Entity
Repository
VIPER
View
Interactor
Presenter
Entity
Repository
An interface which wraps our UI components:
• It should allow the presenter to communicate at a
higher level of abstraction, express in terms on its
content.
• It’s passive, it will wait for the presenter to give it
content to display .
• It will not ask the presenter for content itself.
• It’s not a framework specific interface.
VIPER
View
Interactor
Presenter
Entity
Repository
• It’s where our business logic is at.
• It contains the business logic to manipulate
model objects (entities) and to carry out a specific
task.
• The work done in an Interactor should be
independent of any UI.
• It will communicate with the repositories, server,
and will convert the data to UI objects before
passing it to the presenter.
• It’s a POJO – it handles only POJO data .
• It’s the main area of our testing.
VIPER
View
Interactor
Presenter
Entity
Repository
Mainly consists of the logic about how to drive
the UI:
• It gathers input from user interactions.
• It sends requests to the interactor.
• It tells the view what to show and provides.
the view with content to show.
VIPER
View
Interactor
Presenter
Entity
Repository
It’s just a data model inside your application:
• It’s manipulated by the interaction.
• It’s usually just a POJO.
VIPER Abstracts the storage technique used in an
applications:
• It’s called by the interaction.
• It’s feature specific (or entity specific), thus
following the single responsibility principle.
• Allows us to avoid god classes for DB work
and increases our flexibility.
View
Interactor
Presenter
Entity
Repository
InteractorsPresentersView Interface
Server DB
public interface SomeFeatureVIPER {

interface View {

//some UI abilities, (showProgress, onUsersLoaded)
}
interface Interactor {

//some task which returns some UI data
}
interface Presenter {

// some high level action to be made due
to user input
// or lifecycle event
}
interface Repository {

// some data which is stored in some way
}
}
The
Contract
`
Show me the code!
Company Users – a sample app
public interface EmployeesVIP {

interface View {

void onUsersLoaded(List<Employee> employees);

}
interface Interactor {

Observable<List<Employee>> getTopLevelManagement();

}
interface Presenter {

void showTopLevelManagement();

}
interface Repository {

List<Employee> getTopLevelManagement();

}
}
The
Contract
public class EmployeeInteractor implements EmployeesVIP.Interactor {

private final ServerApi serverApi;

private final EmployeesVIP.Repository repository;

@Inject

public EmployeeInteractor(ServerApi serverApi,
EmployeesVIP.Repository repository) {

this.serverApi = serverApi;

this.repository = repository;

}
The
Interactor
@Override

public Observable<EmployeeResponse> loadEmployees() {

//try to get from db first, if it's empty go to server and
//save data to db

Observable<EmployeeResponse> server =
serverApi.getEmployees()
.doOnNext(repository::saveData);

return repository.getResponse().switchIfEmpty(server);
}
@Override

public Observable<List<Employee>> getTopLevelManagement() {

return Observable.create(subscriber -> {

List<Employee> topLevelManagement =
repository.getTopLevelManagement();

subscriber.onNext(topLevelManagement);

subscriber.onCompleted();

});

}

}






The
Presenter
public class EmployeePresenter extends BasePresenter implements EmployeesVIP.Pre


private final EmployeesVIP.Interactor interactor;

private EmployeesVIP.View view;

@Inject

public EmployeePresenter(EmployeesVIP.Interactor interactor,
EmployeesVIP.View view) { 

this.interactor = interactor;

this.view = view;

}
@Override

public Observable<EmployeeResponse> loadCompany() {

return interactor.loadEmployees()
.observeOn(AndroidSchedulers.mainThread())

.doOnNext(employeeResponse ->
view.setPageTitle(employeeResponse.companyName));
}
@Override

public void showTopLevelManagement() {

Subscription subscribe = interactor.getTopLevelManagement()

.subscribeOn(Schedulers.computation())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(employees -> view.onUsersLoaded(employees),

throwable -> //handle error here);

addSubscription(subscribe);

}

}
public class EmployeeView implements EmployeesVIP.View {



private final AdapterEmployees adapter;



@BindView(R.id.recycler_view)

RecyclerView recyclerView;



@BindView(R.id.view_switcher)

ViewSwitcher viewSwitcher;



public EmployeeView(AppCompatActivity activity,
AdapterEmployees adapter) { 

this.adapter = adapter;

ButterKnife.bind(this, activity);

recyclerView.setLayoutManager(new GridLayoutManager(activity, 3));

recyclerView.setAdapter(adapter);

}
The
View
@Override

public void onUsersLoaded(List<Employee> employees) {

if (viewSwitcher.getCurrentView().getId() == R.id.progress_bar) {

viewSwitcher.showNext();

}

adapter.setData(employees);

}

}
public class ActivityTopLevelManagement extends
ActivityBaseEmployee {



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_top_managers);

ButterKnife.bind(this);

bindEmployeePresenter();



presenter.loadCompany()

.subscribe(employeeResponse->
presenter.showTopLevelManagement());

}



}
The
Android
Ω InteractorsPresenters
View
Interface
Boundaries will set us free
Testing
Broadcast receivers
Services
3rd Parties
Navigation
J Unit
Testing
@RunWith(MockitoJUnitRunner.class)

public class EmployeeInteractorTest {
@Mock

ServerApi serverApi;


@Before

public void setup() {

interactor = new EmployeeInteractor(serverApi, repository);

}
@Test

public void when_db_is_empty_will_save_to_db() {

when(repository.getResponse())
.thenReturn(Observable.empty());
when(serverApi.getEmployees())
.thenReturn(Observable.just(mockResponse));



interactor.loadEmployees().subscribe();

verify(repository).saveData(mockResponse);

}
}
Questions?
Resources
Sample App:
https://github.com/DaPulse/AndroidVIPER.git
Coursera Viper+MVVM:
https://realm.io/news/360andev-richa-khandelwal-effective-android-architecture-patterns-java/
Thank you :)

More Related Content

What's hot

Spring from a to Z
Spring from  a to ZSpring from  a to Z
Spring from a to Zsang nguyen
 
Introduction to Ibatis by Rohit
Introduction to Ibatis by RohitIntroduction to Ibatis by Rohit
Introduction to Ibatis by RohitRohit Prabhakar
 
Marlabs - ASP.NET Concepts
Marlabs - ASP.NET ConceptsMarlabs - ASP.NET Concepts
Marlabs - ASP.NET ConceptsMarlabs
 
Externalizing Authorization in Micro Services world
Externalizing Authorization in Micro Services worldExternalizing Authorization in Micro Services world
Externalizing Authorization in Micro Services worldSitaraman Lakshminarayanan
 
Utilizing JSF Front Ends with Microservices
Utilizing JSF Front Ends with MicroservicesUtilizing JSF Front Ends with Microservices
Utilizing JSF Front Ends with MicroservicesJosh Juneau
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentationguest11106b
 
.NET Core, ASP.NET Core Course, Session 13
.NET Core, ASP.NET Core Course, Session 13.NET Core, ASP.NET Core Course, Session 13
.NET Core, ASP.NET Core Course, Session 13aminmesbahi
 
Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionDinesh Sharma
 
Spring Framework Tutorial | VirtualNuggets
Spring Framework Tutorial | VirtualNuggetsSpring Framework Tutorial | VirtualNuggets
Spring Framework Tutorial | VirtualNuggetsVirtual Nuggets
 
Spring MVC framework
Spring MVC frameworkSpring MVC framework
Spring MVC frameworkMohit Gupta
 
Anypointconnectordevkit 160816041722
Anypointconnectordevkit 160816041722Anypointconnectordevkit 160816041722
Anypointconnectordevkit 160816041722ppts123456
 
Lecture 1: Introduction to JEE
Lecture 1:  Introduction to JEELecture 1:  Introduction to JEE
Lecture 1: Introduction to JEEFahad Golra
 
Session 43 - Spring - Part 1 - IoC DI Beans
Session 43 - Spring - Part 1 - IoC DI BeansSession 43 - Spring - Part 1 - IoC DI Beans
Session 43 - Spring - Part 1 - IoC DI BeansPawanMM
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkASG
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Hitesh-Java
 
Validate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation apiValidate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation apiRaffaele Chiocca
 

What's hot (20)

Spring from a to Z
Spring from  a to ZSpring from  a to Z
Spring from a to Z
 
Introduction to Ibatis by Rohit
Introduction to Ibatis by RohitIntroduction to Ibatis by Rohit
Introduction to Ibatis by Rohit
 
Marlabs - ASP.NET Concepts
Marlabs - ASP.NET ConceptsMarlabs - ASP.NET Concepts
Marlabs - ASP.NET Concepts
 
Externalizing Authorization in Micro Services world
Externalizing Authorization in Micro Services worldExternalizing Authorization in Micro Services world
Externalizing Authorization in Micro Services world
 
Utilizing JSF Front Ends with Microservices
Utilizing JSF Front Ends with MicroservicesUtilizing JSF Front Ends with Microservices
Utilizing JSF Front Ends with Microservices
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 
.NET Core, ASP.NET Core Course, Session 13
.NET Core, ASP.NET Core Course, Session 13.NET Core, ASP.NET Core Course, Session 13
.NET Core, ASP.NET Core Course, Session 13
 
Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency Injection
 
Spring Framework Tutorial | VirtualNuggets
Spring Framework Tutorial | VirtualNuggetsSpring Framework Tutorial | VirtualNuggets
Spring Framework Tutorial | VirtualNuggets
 
L06 Using Design Patterns
L06 Using Design PatternsL06 Using Design Patterns
L06 Using Design Patterns
 
Spring MVC framework
Spring MVC frameworkSpring MVC framework
Spring MVC framework
 
Anypointconnectordevkit 160816041722
Anypointconnectordevkit 160816041722Anypointconnectordevkit 160816041722
Anypointconnectordevkit 160816041722
 
Lecture 1: Introduction to JEE
Lecture 1:  Introduction to JEELecture 1:  Introduction to JEE
Lecture 1: Introduction to JEE
 
Apiworld
ApiworldApiworld
Apiworld
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 
Session 43 - Spring - Part 1 - IoC DI Beans
Session 43 - Spring - Part 1 - IoC DI BeansSession 43 - Spring - Part 1 - IoC DI Beans
Session 43 - Spring - Part 1 - IoC DI Beans
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
 
Validate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation apiValidate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation api
 
Spring Framework Rohit
Spring Framework RohitSpring Framework Rohit
Spring Framework Rohit
 

Similar to Android meetup

React gsg presentation with ryan jung &amp; elias malik
React   gsg presentation with ryan jung &amp; elias malikReact   gsg presentation with ryan jung &amp; elias malik
React gsg presentation with ryan jung &amp; elias malikLama K Banna
 
Building a blog with an Onion Architecture
Building a blog with an Onion ArchitectureBuilding a blog with an Onion Architecture
Building a blog with an Onion ArchitectureBarry O Sullivan
 
Onion Architecture and the Blog
Onion Architecture and the BlogOnion Architecture and the Blog
Onion Architecture and the Blogbarryosull
 
Spring intro classes-in-mumbai
Spring intro classes-in-mumbaiSpring intro classes-in-mumbai
Spring intro classes-in-mumbaivibrantuser
 
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...MskDotNet Community
 
AngularJS 1.x - your first application (problems and solutions)
AngularJS 1.x - your first application (problems and solutions)AngularJS 1.x - your first application (problems and solutions)
AngularJS 1.x - your first application (problems and solutions)Igor Talevski
 
Service Oriented Architecture in NodeJS
Service Oriented Architecture in NodeJSService Oriented Architecture in NodeJS
Service Oriented Architecture in NodeJSAndolasoft Inc
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidOutware Mobile
 
Ejb course-in-mumbai
Ejb course-in-mumbaiEjb course-in-mumbai
Ejb course-in-mumbaivibrantuser
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternNitin Bhide
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerPaul Jones
 
Intorduction to struts
Intorduction to strutsIntorduction to struts
Intorduction to strutsAnup72
 
Fed London - January 2015
Fed London - January 2015Fed London - January 2015
Fed London - January 2015Phil Leggetter
 
Basic React Knowledge.
Basic React Knowledge.Basic React Knowledge.
Basic React Knowledge.jacobryne
 
Spring introduction
Spring introductionSpring introduction
Spring introductionManav Prasad
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Codejameshalsall
 

Similar to Android meetup (20)

Hybernat and structs, spring classes in mumbai
Hybernat and structs, spring classes in mumbaiHybernat and structs, spring classes in mumbai
Hybernat and structs, spring classes in mumbai
 
React gsg presentation with ryan jung &amp; elias malik
React   gsg presentation with ryan jung &amp; elias malikReact   gsg presentation with ryan jung &amp; elias malik
React gsg presentation with ryan jung &amp; elias malik
 
Building a blog with an Onion Architecture
Building a blog with an Onion ArchitectureBuilding a blog with an Onion Architecture
Building a blog with an Onion Architecture
 
Onion Architecture and the Blog
Onion Architecture and the BlogOnion Architecture and the Blog
Onion Architecture and the Blog
 
Spring intro classes-in-mumbai
Spring intro classes-in-mumbaiSpring intro classes-in-mumbai
Spring intro classes-in-mumbai
 
Spring
SpringSpring
Spring
 
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
 
AngularJS 1.x - your first application (problems and solutions)
AngularJS 1.x - your first application (problems and solutions)AngularJS 1.x - your first application (problems and solutions)
AngularJS 1.x - your first application (problems and solutions)
 
Service Oriented Architecture in NodeJS
Service Oriented Architecture in NodeJSService Oriented Architecture in NodeJS
Service Oriented Architecture in NodeJS
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on Android
 
Ejb course-in-mumbai
Ejb course-in-mumbaiEjb course-in-mumbai
Ejb course-in-mumbai
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design pattern
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
 
Java part 3
Java part  3Java part  3
Java part 3
 
Spring
SpringSpring
Spring
 
Intorduction to struts
Intorduction to strutsIntorduction to struts
Intorduction to struts
 
Fed London - January 2015
Fed London - January 2015Fed London - January 2015
Fed London - January 2015
 
Basic React Knowledge.
Basic React Knowledge.Basic React Knowledge.
Basic React Knowledge.
 
Spring introduction
Spring introductionSpring introduction
Spring introduction
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Code
 

More from Vitali Pekelis

Droidkaigi2019thagikura 190208135940
Droidkaigi2019thagikura 190208135940Droidkaigi2019thagikura 190208135940
Droidkaigi2019thagikura 190208135940Vitali Pekelis
 
Google i o &amp; android q changes 2019
Google i o &amp; android q changes 2019Google i o &amp; android q changes 2019
Google i o &amp; android q changes 2019Vitali Pekelis
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architectureVitali Pekelis
 
Advanced #4 GPU & Animations
Advanced #4   GPU & AnimationsAdvanced #4   GPU & Animations
Advanced #4 GPU & AnimationsVitali Pekelis
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networkingVitali Pekelis
 
Advanced #1 cpu, memory
Advanced #1   cpu, memoryAdvanced #1   cpu, memory
Advanced #1 cpu, memoryVitali Pekelis
 
All the support you need. Support libs in Android
All the support you need. Support libs in AndroidAll the support you need. Support libs in Android
All the support you need. Support libs in AndroidVitali Pekelis
 
How to build Sdk? Best practices
How to build Sdk? Best practicesHow to build Sdk? Best practices
How to build Sdk? Best practicesVitali Pekelis
 
Android design patterns
Android design patternsAndroid design patterns
Android design patternsVitali Pekelis
 
Advanced #3 threading
Advanced #3  threading Advanced #3  threading
Advanced #3 threading Vitali Pekelis
 
Mobile ui fruit or delicious sweets
Mobile ui  fruit or delicious sweetsMobile ui  fruit or delicious sweets
Mobile ui fruit or delicious sweetsVitali Pekelis
 
Lecture #4 c loaders and co.
Lecture #4 c   loaders and co.Lecture #4 c   loaders and co.
Lecture #4 c loaders and co.Vitali Pekelis
 
Session #4 b content providers
Session #4 b  content providersSession #4 b  content providers
Session #4 b content providersVitali Pekelis
 
Advanced #2 - ui perf
 Advanced #2 - ui perf Advanced #2 - ui perf
Advanced #2 - ui perfVitali Pekelis
 
Android design lecture #3
Android design   lecture #3Android design   lecture #3
Android design lecture #3Vitali Pekelis
 

More from Vitali Pekelis (20)

Droidkaigi2019thagikura 190208135940
Droidkaigi2019thagikura 190208135940Droidkaigi2019thagikura 190208135940
Droidkaigi2019thagikura 190208135940
 
Droidkaigi 2019
Droidkaigi 2019Droidkaigi 2019
Droidkaigi 2019
 
Google i o &amp; android q changes 2019
Google i o &amp; android q changes 2019Google i o &amp; android q changes 2019
Google i o &amp; android q changes 2019
 
Android Q 2019
Android Q 2019Android Q 2019
Android Q 2019
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architecture
 
Advanced #4 GPU & Animations
Advanced #4   GPU & AnimationsAdvanced #4   GPU & Animations
Advanced #4 GPU & Animations
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networking
 
Advanced #2 threading
Advanced #2   threadingAdvanced #2   threading
Advanced #2 threading
 
Advanced #1 cpu, memory
Advanced #1   cpu, memoryAdvanced #1   cpu, memory
Advanced #1 cpu, memory
 
All the support you need. Support libs in Android
All the support you need. Support libs in AndroidAll the support you need. Support libs in Android
All the support you need. Support libs in Android
 
How to build Sdk? Best practices
How to build Sdk? Best practicesHow to build Sdk? Best practices
How to build Sdk? Best practices
 
Di &amp; dagger
Di &amp; daggerDi &amp; dagger
Di &amp; dagger
 
Android design patterns
Android design patternsAndroid design patterns
Android design patterns
 
Advanced #3 threading
Advanced #3  threading Advanced #3  threading
Advanced #3 threading
 
Mobile ui fruit or delicious sweets
Mobile ui  fruit or delicious sweetsMobile ui  fruit or delicious sweets
Mobile ui fruit or delicious sweets
 
Lecture #4 c loaders and co.
Lecture #4 c   loaders and co.Lecture #4 c   loaders and co.
Lecture #4 c loaders and co.
 
Session #4 b content providers
Session #4 b  content providersSession #4 b  content providers
Session #4 b content providers
 
Advanced #2 - ui perf
 Advanced #2 - ui perf Advanced #2 - ui perf
Advanced #2 - ui perf
 
Android design lecture #3
Android design   lecture #3Android design   lecture #3
Android design lecture #3
 
From newbie to ...
From newbie to ...From newbie to ...
From newbie to ...
 

Recently uploaded

Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 

Recently uploaded (20)

Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 

Android meetup

  • 1. How to build fast, clean and flexible Android architecture
  • 3. The art or science of building a unifying or coherent form or structure. Architecture
  • 4.
  • 6. Our Goal Code • Easy to iterate on • Collaboration-friendly • Separated concerns • Easy to test
  • 7. Why does Android Suck at testing? • Activities, Services, Broadcast Receivers, Content Providers, Bundles, Intents • Fragments, Views, Notifications, Resources • Databases, IPC, Threads, Storage • Thousands of APIs related to services and specific hardware features of devices • Support libraries and external third party libraries
  • 8. Single responsibility Open/close Liskov substitution principle Interface segregation principle Dependency inversion principle SOLID
  • 9. Dependency Injection What we can easily replace – we can easily test By declaring on which other components or abilities our current component depends, we get: • Decoupled code • Better understanding of what this components does, and what it needs • Replaceable and extendible code • Easy to mock and test Watch out for static class and new variable declarations
  • 10. Dependency Injection What we can easily replace – we can easily test
  • 11. public class RateUsManager {
 public RateUsManager(Context context) {
 this.context = context; this.prefs = PreferenceManager.getDefaultShared Preferences(app); this.analytics = new Analytics(context); } public void showIfNeeded { if (lots of code conditions depending on prefs) { prefs.edit().putInt(RATE_US_SHOWN, prefs.getInt(RATE_US_SHOWN,0) + 1); analytics.report(“rate us shown”); } } private void reportRate(int starts) {
 NetworkManager.reportRate(starts); } } Dependency Injection
  • 12. public class RateUsManager {
 public RateUsManager(RateUsPrefrences ratePrefs, NetworkModule networkManager, AnalyticsHelper analytics) {
 } public void showIfNeeded { if (ratePrefs.shouldShow()) { ratePrefs.increaseShowCount(); analytics.report(“rate us shown”); } } private void reportRate(int starts) {
 networkManager.reportRate(starts); } } Dependency Injection
  • 13. Independent Business Logic We want to separate our business logic code from the framework independent code: • It will make our code more reusable • It will make our code better structured and easier to maintain • Testing will become much clearer
  • 16. VIPER View Interactor Presenter Entity Repository An interface which wraps our UI components: • It should allow the presenter to communicate at a higher level of abstraction, express in terms on its content. • It’s passive, it will wait for the presenter to give it content to display . • It will not ask the presenter for content itself. • It’s not a framework specific interface.
  • 17. VIPER View Interactor Presenter Entity Repository • It’s where our business logic is at. • It contains the business logic to manipulate model objects (entities) and to carry out a specific task. • The work done in an Interactor should be independent of any UI. • It will communicate with the repositories, server, and will convert the data to UI objects before passing it to the presenter. • It’s a POJO – it handles only POJO data . • It’s the main area of our testing.
  • 18. VIPER View Interactor Presenter Entity Repository Mainly consists of the logic about how to drive the UI: • It gathers input from user interactions. • It sends requests to the interactor. • It tells the view what to show and provides. the view with content to show.
  • 19. VIPER View Interactor Presenter Entity Repository It’s just a data model inside your application: • It’s manipulated by the interaction. • It’s usually just a POJO.
  • 20. VIPER Abstracts the storage technique used in an applications: • It’s called by the interaction. • It’s feature specific (or entity specific), thus following the single responsibility principle. • Allows us to avoid god classes for DB work and increases our flexibility. View Interactor Presenter Entity Repository
  • 22. public interface SomeFeatureVIPER {
 interface View {
 //some UI abilities, (showProgress, onUsersLoaded) } interface Interactor {
 //some task which returns some UI data } interface Presenter {
 // some high level action to be made due to user input // or lifecycle event } interface Repository {
 // some data which is stored in some way } } The Contract
  • 23. ` Show me the code! Company Users – a sample app
  • 24.
  • 25. public interface EmployeesVIP {
 interface View {
 void onUsersLoaded(List<Employee> employees);
 } interface Interactor {
 Observable<List<Employee>> getTopLevelManagement();
 } interface Presenter {
 void showTopLevelManagement();
 } interface Repository {
 List<Employee> getTopLevelManagement();
 } } The Contract
  • 26. public class EmployeeInteractor implements EmployeesVIP.Interactor {
 private final ServerApi serverApi;
 private final EmployeesVIP.Repository repository;
 @Inject
 public EmployeeInteractor(ServerApi serverApi, EmployeesVIP.Repository repository) {
 this.serverApi = serverApi;
 this.repository = repository;
 } The Interactor @Override
 public Observable<EmployeeResponse> loadEmployees() {
 //try to get from db first, if it's empty go to server and //save data to db
 Observable<EmployeeResponse> server = serverApi.getEmployees() .doOnNext(repository::saveData);
 return repository.getResponse().switchIfEmpty(server); } @Override
 public Observable<List<Employee>> getTopLevelManagement() {
 return Observable.create(subscriber -> {
 List<Employee> topLevelManagement = repository.getTopLevelManagement();
 subscriber.onNext(topLevelManagement);
 subscriber.onCompleted();
 });
 }
 }
  • 27. 
 
 
 The Presenter public class EmployeePresenter extends BasePresenter implements EmployeesVIP.Pre 
 private final EmployeesVIP.Interactor interactor;
 private EmployeesVIP.View view;
 @Inject
 public EmployeePresenter(EmployeesVIP.Interactor interactor, EmployeesVIP.View view) { 
 this.interactor = interactor;
 this.view = view;
 } @Override
 public Observable<EmployeeResponse> loadCompany() {
 return interactor.loadEmployees() .observeOn(AndroidSchedulers.mainThread())
 .doOnNext(employeeResponse -> view.setPageTitle(employeeResponse.companyName)); } @Override
 public void showTopLevelManagement() {
 Subscription subscribe = interactor.getTopLevelManagement()
 .subscribeOn(Schedulers.computation())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(employees -> view.onUsersLoaded(employees),
 throwable -> //handle error here);
 addSubscription(subscribe);
 }
 }
  • 28. public class EmployeeView implements EmployeesVIP.View {
 
 private final AdapterEmployees adapter;
 
 @BindView(R.id.recycler_view)
 RecyclerView recyclerView;
 
 @BindView(R.id.view_switcher)
 ViewSwitcher viewSwitcher;
 
 public EmployeeView(AppCompatActivity activity, AdapterEmployees adapter) { 
 this.adapter = adapter;
 ButterKnife.bind(this, activity);
 recyclerView.setLayoutManager(new GridLayoutManager(activity, 3));
 recyclerView.setAdapter(adapter);
 } The View @Override
 public void onUsersLoaded(List<Employee> employees) {
 if (viewSwitcher.getCurrentView().getId() == R.id.progress_bar) {
 viewSwitcher.showNext();
 }
 adapter.setData(employees);
 }
 }
  • 29. public class ActivityTopLevelManagement extends ActivityBaseEmployee {
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_top_managers);
 ButterKnife.bind(this);
 bindEmployeePresenter();
 
 presenter.loadCompany()
 .subscribe(employeeResponse-> presenter.showTopLevelManagement());
 }
 
 } The Android
  • 30. Ω InteractorsPresenters View Interface Boundaries will set us free Testing Broadcast receivers Services 3rd Parties Navigation
  • 31. J Unit Testing @RunWith(MockitoJUnitRunner.class)
 public class EmployeeInteractorTest { @Mock
 ServerApi serverApi; 
 @Before
 public void setup() {
 interactor = new EmployeeInteractor(serverApi, repository);
 } @Test
 public void when_db_is_empty_will_save_to_db() {
 when(repository.getResponse()) .thenReturn(Observable.empty()); when(serverApi.getEmployees()) .thenReturn(Observable.just(mockResponse));
 
 interactor.loadEmployees().subscribe();
 verify(repository).saveData(mockResponse);
 } }