SlideShare a Scribd company logo
Intro
1. Goals
2. Structure
3. Challenges
Architectural	decisions
UI Presenter Repository
Local
storage
Remote
storage
1. Retrofit
2. Crashlytics
3. Gson
1. Gson
2. SharedPrefs
3. Realm(in	plans)
1. rxjava1. Rxjava
2. Glide
3. Support	(Constrain	
layout)
4. DataBinding
5. Facebook	sdk
6. Firebase
7. VK	sdk
8. Custom	views
1. Retrolambda
2. Dagger
3. annimon:stream
4. Crashlytics
5. Own	libs
Dagger2	advocating
1. Reusable	code	
2. Testability
3. Easy	scalability
4. Boilerplate	code	reduction*
Dagger2	structure	in	R.I.D.
AppComponent:
- Repository
- Context
Activity1:
Inject	in	Activity1	class	
Repository
Activity2:
Inject	in	Activity1	class	
Repository
ActivityN:
Inject	in	Activity1	class	
Repository
(first	edition)
Not	so	good	L
Dagger2	structure	in	R.I.D.
AppComponent:
- Repository
- Context
- ModuleFactory BaseActivityComponent:
- BaseActivity Presenters
(Inject	in	BaseActivity class)
ActivityComponent_1:
- Activity_1	Presenters
(Inject	in	Activity1	class)
ActivityComponent_2:
- Activity_2	Presenters
(Inject	in	Activity2	class)
ActivityComponent_N:
- Activity_1	Presenters
(Inject	in	ActivityN class)
Any	other	app	component
(second	edition)
Dagger2	structure	in	R.I.D.
(code	samples)
AppComponent
AppModule
@Module
public class AppModule {
@Singleton
@Provides
public Context provideContext() {return mContext;}
@Singleton
@Provides
public Repository provideRepository() {
return getRepository();}
@Provides
@Singleton
public PresenterFactoryExtended provideExtendedModuleFactory() {
return getExtendedModuleFactory();}
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(IntroActivity activity);
void inject(SplashActivity activity);
PresenterFactoryExtended getExtendedPresenterFactory();
BaseActivityComponent plus(BaseActivityModule module);
}
Dagger2	structure	in	R.I.D.
(code	samples)
BaseActivityComponent
BaseActivityModule
@Module
@Singleton
public class BaseActivityModule {
@Provides
public SuggestWordPresenter provideSuggestPresenter(Repository repository) {
return getSuggestPresenter(repository);
}
@Provides
@Named("BaseActivity")
public UserAccountPresenter provideUserPresenter(Repository repository) {
return getUserPresenter(repository);
}
@BaseActivityScope
@Subcomponent(modules = BaseActivityModule.class)
@Singleton
public interface BaseActivityComponent {
void inject(BaseActivity activity);
PresenterFactory getScopeModule();
FirstComponent plus(FirstModule module);
…
NthComponent plus(NthModule module);
}
Dagger2	structure	in	R.I.D.
(code	samples)
In	BaseActivity class
That	is	all:	just	use	presenter	now
In	Activity	class
P.S.	Have	you	noticed	generated	classes?
public BaseActivityComponent getBaseActivityComponent() {
if (baseactivityComponent == null) {
AppComponent comp = ((RidApp) getApplication()).getAppComponent();
baseactivityComponent = comp.plus(comp.getExtendedPresenterFactory()
.provideBaseActivityModule(this, this));
}
return baseactivityComponent;
}
@Inject DictionaryPresenter mPresenter;
private void injectDependencies() {
mDictionaryComponent =
getAppComponent().plus(getBaseActivityComponent().getScopeModule().getModule(this));
mDictionaryComponent.inject(this);
}
Dagger2	structure	in	R.I.D.
(code	samples)
ActivityComponent
ActivityModule
package com.smartpresenter.generated;
@Module
public class DailyWordsModule {
private com.ua.rid.contract.DailyWordsContract.View mContract;
public DailyWordsModule(com.ua.rid.contract.DailyWordsContract.View contract) {
this.mContract = contract;
}
@Provides
public com.ua.rid.presenter.DailyWordsPresenter providePresenter(com.ua.rid.model.Repository repository){
return getPresenter(repository);
}
package com.smartpresenter.generated;
import dagger.Subcomponent;
import com.ua.rid.di.ActivityScope;
@ActivityScope
@Subcomponent(modules =
com.smartpresenter.generated.DailyWordsModule.class)
public interface DailyWordsComponent {
void inject(com.ua.rid.ui.activity.DailyWordsActivity target);
}
Dagger2	custom	apt	in	R.I.D.
In	Presenter	class
In	dependencies.gradle
@DaggerSubComponent(
whereToInject = {DailyWordsActivity.class},
repository = Repository.class,
contract = DailyWordsContract.View.class)
public class DailyWordsPresenter extends BasePresenter implements
DailyWordsContract.Presenter {…}
compile files('lib/presenterfactoryprocessor.jar')
Dagger2	custom	apt	in	R.I.D.
@Target(ElementType.TYPE)
public @interface DaggerSubComponent {
//List of classes where this presenter will be used
Class[] whereToInject() default {};
//Repository to which this presenter would refer
Class repository() default XmlJavaTypeAdapter.DEFAULT.class;
//View Contract for callBacks
Class contract() default XmlJavaTypeAdapter.DEFAULT.class;
}
Custom	annotation
@SupportedAnnotationTypes("com.processor.DaggerSubComponent")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class PresenterFactoryProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//Do your magic here…
return true;
}
Generate	code
- How	to	write	classes	to	be	generated
- Few	words	about	apt	sequence
Test	advocating
1. Be	sure	in	your	code	validity	
2. Makes	your	code	clean	
3. Keep	calm	and	go	refactor
4. Describes	your	dev	level
5. World	wide	trend!!!
UI	Tests
Tests	hook	for	dagger
@Module
public class TestAppModule extends AppModule {
@Override
public PresenterFactory getModuleFactory() {
return Mockito.mock(PresenterFactory.class);
}
@Override
protected PresenterFactoryExtended getExtendedModuleFactory() {
return Mockito.mock(PresenterFactoryExtended.class);
}
@NonNull
@Override
public Repository getRepository() {
return Mockito.mock(Repository.class);
}
}
1.	Override	AppModule and	return	mocks
UI	Tests
Tests	hook	for	dagger
2.	Create	custom	test	rule
public class MyTestRule implements TestRule {
public MyTestRule(Context context) {
…
mTestComponent = DaggerTestAppComponent
.builder()
.testAppModule(new TestAppModule(application.getApplicationContext())).build();
}
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
…
application.setMainComponent(mTestComponent);
base.evaluate();
application.setMainComponent(null);
}
};
}
}
UI	Tests
Tests	hook	for	dagger
3.	Chain	rules	in	test
final MyTestRule component =
new MyTestRule(InstrumentationRegistry.getTargetContext());
private final ActivityTestRule<DailyWordsActivity> mActivityRule =
new ActivityTestRule<>(YourActivity.class, false, false);
@Rule
public TestRule chain = RuleChain.outerRule(component).around(mActivityRule);
@Override
public void setUp() {
super.setUp();
setUpPresenter();
}
private void setUpPresenter() {
when(mMockPresenterFactory.getModule(mCallBackCaptor.capture())).thenReturn(mMockModule);
when(mMockModule.providePresenter(any())).thenReturn(mMockPresenter);
}
4.	SetUp your	mocks
UI	Tests
Simplicity	of	Espresso
onView(withId(R.id.tv_mainWord1)).check(matches(withText("test1")));
Check	if	given	view	shows	needed	text
onView(withId(R.id.dictionary_recycler_view)).check(new RecyclerViewItemCountAssertion(6));
Check	if	given	RecyclerView has	6	childs (custom	ViewAssertion)
if (isElementVisible(withId(R.id.dictionary_recycler_view))) {
onView(withId(R.id.dictionary_recycler_view)).perform(RecyclerViewActions
.actionOnItemAtPosition(1, click()));
//check intent
intended(expectedIntent);
Intents.release();
} else {
assertTrue("Failed to find recycler", false);
}
Click	RecyclerView child	at	position	==	1	and	check	intent
Espresso	cheat	sheet
UI	Tests
What	exactly	is	tested?
1. View logic	(what	will	happen	if	one	clicks	this	
button?)
2. Do	not	test	presenters	- MOCK	them	
3. Be	aware	of	animations	(of	any	kind)
4. Do	not	test	changes	of	activities/fragments/etc -
test	intents
Unit	tests
Again	what	exactly	is	tested?
1. Test	YOUR	logic	(2	+	2	=	4?)
2. Test	edge	cases
3. Avoid	testing	android
4. Do	not	test	3d	party	libs	(smbd`s already	done)
5. Try	to	test	all	public	methods
6. I`m	pretty	sure	U	must	not	test	private	methods… (if	your	
code	is	good	it`s	done	automatically)
Unit	tests
RX	Schedulers
io()	is	waiting	for	smth but	test	won`t.	Custom	Scheduler
public class AppSchedulers {
public interface SchedulerProvider {
Scheduler mainThread();
Scheduler io();
}
public static Scheduler mainThread() {
return instance.mainThread();
}
public static Scheduler io() {
return instance.io();
}
public static class DefaultSchedulerProvider implements SchedulerProvider {
@Override
public Scheduler mainThread() {
return AndroidSchedulers.mainThread();
}
@Override
public Scheduler io() {
return Schedulers.io();
}
}
}
Unit	tests
RX	Schedulers
Custom	rule	->	substitute	real	Scheduler
public class SynchronousSchedulers extends ExternalResource {
@Override
protected void before() throws Throwable {
AppSchedulers.setInstance(new AppSchedulers.SchedulerProvider() {
@Override
public Scheduler mainThread() {
return Schedulers.immediate();
}
@Override
public Scheduler io() {
return Schedulers.immediate();
}
});
}
@Override
protected void after() {
AppSchedulers.setInstance(new AppSchedulers.DefaultSchedulerProvider());
}
}
Yes,	I	know	about	TestSubscriber,	but	it`s	our	LSD,	our	universe,	our	Schedulers))))
Tests	approach	and	TDD	Holly	War
1. My	way 2.	R.I.D.	way
Reading	test	results
1. UI	+	unit	results
2. Lines	coverage
3. Branches	cov.
4. Static	code	analysis	
few	words
How	to	merge	coverage*
Plans
1. Continuous	integration
2. Apps	environment	infrastructure	(more	apps)	
3. Project	infrastructure	(marketing,	offline	events)
We	are	hiring
1. IOS	dev
2. Android	dev
3. BackEnd (Ruby)	dev
4. UI/UX	designer
5. Front	end	developer
Find	us:
http://rid.ck.ua/
The	end
Sergiy	Grechukha
Android	Engineer,	Techery
mail:	sergey.grechukha@gmail.com
com.ua.rid D/AndroidRuntime:	Shutting	down	VM

More Related Content

What's hot (20)

PDF
Apache DeltaSpike
os890
 
PDF
OpenWebBeans and DeltaSpike at ApacheCon
os890
 
PDF
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
shaunthomas999
 
PDF
Java SE 9 modules (JPMS) - an introduction
Stephen Colebourne
 
PPTX
Core java
Mallikarjuna G D
 
PDF
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Schalk Cronjé
 
PDF
Testing Django Applications
Gareth Rushgrove
 
PPT
What is Java Technology (An introduction with comparision of .net coding)
Shaharyar khan
 
PDF
Overview of Android Infrastructure
Alexey Buzdin
 
PDF
Introduction maven3 and gwt2.5 rc2 - Lesson 01
rhemsolutions
 
PDF
Toward dynamic analysis of obfuscated android malware
ZongXian Shen
 
PPT
Python Evolution
Quintagroup
 
PDF
Migrating to java 9 modules
Paul Bakker
 
PDF
ProbeDroid - Crafting Your Own Dynamic Instrument Tool on Android for App Beh...
ZongXian Shen
 
PPTX
Quickly Testing Qt Desktop Applications
Clare Macrae
 
PPT
Object Oriented Programming-JAVA
Home
 
PPTX
Core Java introduction | Basics | free course
Kernel Training
 
PPTX
Testing basics for developers
Anton Udovychenko
 
PDF
Java Course 15: Ant, Scripting, Spring, Hibernate
Anton Keks
 
Apache DeltaSpike
os890
 
OpenWebBeans and DeltaSpike at ApacheCon
os890
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
shaunthomas999
 
Java SE 9 modules (JPMS) - an introduction
Stephen Colebourne
 
Core java
Mallikarjuna G D
 
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Schalk Cronjé
 
Testing Django Applications
Gareth Rushgrove
 
What is Java Technology (An introduction with comparision of .net coding)
Shaharyar khan
 
Overview of Android Infrastructure
Alexey Buzdin
 
Introduction maven3 and gwt2.5 rc2 - Lesson 01
rhemsolutions
 
Toward dynamic analysis of obfuscated android malware
ZongXian Shen
 
Python Evolution
Quintagroup
 
Migrating to java 9 modules
Paul Bakker
 
ProbeDroid - Crafting Your Own Dynamic Instrument Tool on Android for App Beh...
ZongXian Shen
 
Quickly Testing Qt Desktop Applications
Clare Macrae
 
Object Oriented Programming-JAVA
Home
 
Core Java introduction | Basics | free course
Kernel Training
 
Testing basics for developers
Anton Udovychenko
 
Java Course 15: Ant, Scripting, Spring, Hibernate
Anton Keks
 

Similar to Android App Architecture with modern libs in practice. Our way in R.I.D., Sergey Grechukha (20)

PDF
Using Dagger in a Clean Architecture project
Fabio Collini
 
PDF
Metamodeling of custom Pharo images
ESUG
 
PPTX
Preparing for java 9 modules upload
Ryan Cuprak
 
PDF
Building Top-Notch Androids SDKs
relayr
 
PDF
Writing Plugged-in Java EE Apps: Jason Lee
jaxconf
 
PDF
A Journey through the JDKs (Java 9 to Java 11)
Markus Günther
 
PPTX
What's New in Java 9
Richard Langlois P. Eng.
 
PDF
Writing Android Libraries
emanuelez
 
PDF
Understanding And Using Reflection
Ganesh Samarthyam
 
PDF
MicroProfile Devoxx.us
jclingan
 
PDF
Daggerate your code - Write your own annotation processor
Bartosz Kosarzycki
 
PDF
Java 9 / Jigsaw - AJUG/VJUG session
Mani Sarkar
 
PPTX
Dynamic Groovy Edges
Jimmy Ray
 
PDF
Fundamental Concepts of React JS for Beginners.pdf
StephieJohn
 
PDF
Workshop 26: React Native - The Native Side
Visual Engineering
 
PDF
DevoxxFR17 - Préparez-vous à la modularité selon Java 9
Alexis Hassler
 
PDF
Devoxx17 - Préparez-vous à la modularité selon Java 9
Alexis Hassler
 
PPTX
Context and Dependency Injection 2.0
Brian S. Paskin
 
PDF
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Nicolas HAAN
 
PDF
Spock
Naiyer Asif
 
Using Dagger in a Clean Architecture project
Fabio Collini
 
Metamodeling of custom Pharo images
ESUG
 
Preparing for java 9 modules upload
Ryan Cuprak
 
Building Top-Notch Androids SDKs
relayr
 
Writing Plugged-in Java EE Apps: Jason Lee
jaxconf
 
A Journey through the JDKs (Java 9 to Java 11)
Markus Günther
 
What's New in Java 9
Richard Langlois P. Eng.
 
Writing Android Libraries
emanuelez
 
Understanding And Using Reflection
Ganesh Samarthyam
 
MicroProfile Devoxx.us
jclingan
 
Daggerate your code - Write your own annotation processor
Bartosz Kosarzycki
 
Java 9 / Jigsaw - AJUG/VJUG session
Mani Sarkar
 
Dynamic Groovy Edges
Jimmy Ray
 
Fundamental Concepts of React JS for Beginners.pdf
StephieJohn
 
Workshop 26: React Native - The Native Side
Visual Engineering
 
DevoxxFR17 - Préparez-vous à la modularité selon Java 9
Alexis Hassler
 
Devoxx17 - Préparez-vous à la modularité selon Java 9
Alexis Hassler
 
Context and Dependency Injection 2.0
Brian S. Paskin
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Nicolas HAAN
 
Ad

More from Sigma Software (20)

PPTX
Fast is Best. Using .NET MinimalAPIs
Sigma Software
 
PPTX
"Are you developing or declining? Don't become an IT-dinosaur"
Sigma Software
 
PPTX
Michael Smolin, "Decrypting customer's cultural code"
Sigma Software
 
PPTX
Max Kunytsia, “Why is continuous product discovery better than continuous del...
Sigma Software
 
PPTX
Marcelino Moreno, "Product Management Mindset"
Sigma Software
 
PDF
Andrii Pastushok, "Product Discovery in Outsourcing - What, When, and How"
Sigma Software
 
PPTX
Elena Turkenych “BA vs PM: Who' the right person, for the right job, with the...
Sigma Software
 
PPTX
Eleonora Budanova “BA+PM+DEV team: how to build the synergy”
Sigma Software
 
PPTX
Stoyan Atanasov “How crucial is the BA role in an IT Project"
Sigma Software
 
PPTX
Olexandra Kovalyova, "Equivalence Partitioning, Boundary Values ​​Analysis, C...
Sigma Software
 
PPTX
Yana Lysa — "Decision Tables, State-Transition testing, Pairwase Testing"
Sigma Software
 
PPTX
VOLVO x HACK SPRINT
Sigma Software
 
PPTX
Business digitalization trends and challenges
Sigma Software
 
PPTX
Дмитро Терещенко, "How to secure your application with Secure SDLC"
Sigma Software
 
PPTX
Яна Лиса, “Ефективні методи написання хороших мануальних тестових сценаріїв”
Sigma Software
 
PDF
Тетяна Осетрова, “Модель зрілості розподіленної проектної команди”
Sigma Software
 
PDF
Training solutions and content creation
Sigma Software
 
PDF
False news - false truth: tips & tricks how to avoid them
Sigma Software
 
PPTX
Анна Бойко, "Хороший контракт vs очікування клієнтів. Що вбереже вас, якщо вд...
Sigma Software
 
PPTX
Дмитрий Лапшин, "The importance of TEX and Internal Quality. How explain and ...
Sigma Software
 
Fast is Best. Using .NET MinimalAPIs
Sigma Software
 
"Are you developing or declining? Don't become an IT-dinosaur"
Sigma Software
 
Michael Smolin, "Decrypting customer's cultural code"
Sigma Software
 
Max Kunytsia, “Why is continuous product discovery better than continuous del...
Sigma Software
 
Marcelino Moreno, "Product Management Mindset"
Sigma Software
 
Andrii Pastushok, "Product Discovery in Outsourcing - What, When, and How"
Sigma Software
 
Elena Turkenych “BA vs PM: Who' the right person, for the right job, with the...
Sigma Software
 
Eleonora Budanova “BA+PM+DEV team: how to build the synergy”
Sigma Software
 
Stoyan Atanasov “How crucial is the BA role in an IT Project"
Sigma Software
 
Olexandra Kovalyova, "Equivalence Partitioning, Boundary Values ​​Analysis, C...
Sigma Software
 
Yana Lysa — "Decision Tables, State-Transition testing, Pairwase Testing"
Sigma Software
 
VOLVO x HACK SPRINT
Sigma Software
 
Business digitalization trends and challenges
Sigma Software
 
Дмитро Терещенко, "How to secure your application with Secure SDLC"
Sigma Software
 
Яна Лиса, “Ефективні методи написання хороших мануальних тестових сценаріїв”
Sigma Software
 
Тетяна Осетрова, “Модель зрілості розподіленної проектної команди”
Sigma Software
 
Training solutions and content creation
Sigma Software
 
False news - false truth: tips & tricks how to avoid them
Sigma Software
 
Анна Бойко, "Хороший контракт vs очікування клієнтів. Що вбереже вас, якщо вд...
Sigma Software
 
Дмитрий Лапшин, "The importance of TEX and Internal Quality. How explain and ...
Sigma Software
 
Ad

Recently uploaded (20)

PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 

Android App Architecture with modern libs in practice. Our way in R.I.D., Sergey Grechukha