SlideShare a Scribd company logo
Extended
Seoul
Architecture Components


alpaca@vcnc.co.kr
Speaker
• (@plazgun)

• Between Android Developer
Architecture Components
• Google I/O 2017 

Architecture Components - Introduction

Architecture Components - Solving the Lifecycle

Architecture Components - Persistence and Offline

• 

• https://developer.android.com/topic/libraries/architecture/
index.html
Architecture Components
• Handling Lifecycles

• LiveData

• ViewModel

• Room
build.gradle
• allprojects {

repositories {

jcenter()

maven { url 'https://maven.google.com' }

}

} 

• compile "android.arch.lifecycle:runtime:1.0.0-alpha3"

compile "android.arch.lifecycle:extensions:1.0.0-alpha3"

annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha3"

• compile "android.arch.persistence.room:runtime:1.0.0-alpha3"

annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha3"

• compile "android.arch.persistence.room:rxjava2:1.0.0-alpha3"

testCompile "android.arch.persistence.room:testing:1.0.0-alpha3"
Handling Lifecycles
public class MyActivity extends AppCompatActivity {
private TestListener testListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testListener = new TestListener();
}
@Override
protected void onStart() {
super.onStart();
testListener.start();
}
@Override
protected void onStop() {
super.onStop();
testListener.stop();
}
}
public class MyActivity extends AppCompatActivity {
private TestListener testListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testListener = new TestListener();
}
@Override
protected void onStart() {
super.onStart();
testListener.start();
}
@Override
protected void onStop() {
super.onStop();
testListener.stop();
}
}
onStart 

Override .
Lifecycle .
Handling Lifecycles
• Lifecycle

• LifecycleOwner

• LifecycleObserver
public class MyActivity extends LifecycleActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle);
TestListener testListener = new TestListener(

getLifecycle(), 

result -> {
// update UI
});
}
}
public class TestListener implements LifecycleObserver {
private Lifecycle lifecycle;
public TestListener(Lifecycle lifecycle, TestCallback callback) {
lifecycle.addObserver(this);
this.lifecycle = lifecycle;
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// start Event
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void clean() {
lifecycle.removeObserver(this);
}
}
public class MyActivity extends CustomActivity {
@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}
}
public class LifecycleActivity extends FragmentActivity 

implements LifecycleRegistryOwner {
private final LifecycleRegistry mRegistry 

= new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return mRegistry;
}
}
public class MyActivity extends CustomActivity implements LifecycleRegistryOwner {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle);
TestListener testListener = new TestListener(getLifecycle(), state -> {
// update Ui
});
}
}
public class MyActivity extends LifecycleActivity {
private TestListener testListener;
@Override
protected void onStart() {
super.onStart();
Utils.checkUserStatus(state -> {
if (state.equals("OK")) {
testListener.start();
}
});
}
public class MyActivity extends LifecycleActivity {
private TestListener testListener;
@Override
protected void onStart() {
super.onStart();
// ?
Utils.checkUserStatus(state -> {
if (state.equals("OK")) {
testListener.start();
}
});
}
StartCreate Resume Pause Stop Destroy
testListener.stop
Utils.checkStatus testListener.start
Activity .
public class MyActivity extends LifecycleActivity {
private TestListener testListener;
@Override
protected void onStart() {
super.onStart();
Utils.checkUserStatus(state -> {
if (state.equals("OK") && getLifecycle()

.getCurrentState()

.isAtLeast(Lifecycle.State.STARTED)) {
testListener.start();
}
});
}
LiveData
LiveData
• Observable Data Holder

• Lifecycle aware

• Automatic subscription management
LiveData<String> stateData = new MutableLiveData<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
stateData.observe((LifecycleOwner) this, ((String) result) -> {
// stateData .
});
}
@Override
protected void onStart() {
super.onStart();
stateData.setValue(“Start");
}
public class StateChangeLiveData extends MutableLiveData<String> {
@Override
protected void onActive() {
super.onActive();

// Active Observer 

// Active: Lifecycle.State STARTED RESUMED
}
@Override
protected void onInactive() {
super.onInactive();

// Active Observer
}
}
ViewModel
public class MyActivity extends LifecycleActivity {
LiveData<User> userData;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
userData = userRepository.fetchData();
userData.observe(this, user -> {
// update UI
});
}
}
StartCreate Resume Pause Stop Destroy
Rotated
fetchData
StartCreate Resume
fetchData
Activity 

.
ViewModel
The ViewModel class is designed to store
and manage UI-related data so that the
data survives configuration changes such
as screen rotations.
”
“
public class UserViewModel extends ViewModel {
}



public class UserViewModel extends AndroidViewModel {

// Application ViewModel

}
ViewModel
• 

• ActivityContext 

• Resource
public class MyActivity extends LifecycleActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.insert_activity);


// ViewModelStore ViewModel .
UserListViewModel viewModel = ViewModelProviders.of(this)

.get(UserListViewModel.class);
public class MyActivity extends LifecycleActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProviders.of(this).get(UserListViewModel.class)
.getData()
.observe(this, user -> {
//update UI
});
public class UserListViewModel extends ViewModel {

private LiveData<User> userLiveData;



public LiveData<User> getData() {

if (userLiveData == null) {

userLiveData = userRepository.fetchData();

}

return userLiveData;

}

}
StartCreate Resume Pause Stop Destroy
Rotated
fetchData
StartCreate Resume
fetchData
StartCreate Resume Pause Stop Destroy
Rotated
StartCreate Resume
ViewModel
fetchData
getData getData
Room
Room
• Sqlite ORM

• Entity

• Dao

• Database
id name create_time
@Entity
public class User {
@PrimaryKey(autoGenerate = true)
private Long id;
String name;
@ColumnInfo(name = "created_time")
private long createdTime;
@Ignore
Bitmap profile;
}
Entity
DAO
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE id IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE name LIKE :first LIMIT 1")
User findByName(String first);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(User... users);
@Delete
void delete(User user);
@Update
void updateUser(User user);
DAO (Rx, LiveData)
@Query("SELECT * FROM user")
LiveData<List<User>> getAllSync();
@Query("SELECT * FROM user WHERE id = :userId")
LiveData<User> fetchUser(String userId);
@Query("SELECT * from user where id = :id LIMIT 1")
Flowable<User> loadUserByIdRx(int id);
@Query("SELECT * FROM user WHERE age > :minAge LIMIT 5")
Cursor loadRawUsersOlderThan(int minAge);
Database
@Database(entities = {User.class, Book.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {


public abstract UserDao userDao();
public abstract BookDao bookDao();
}
Entity - Embedded
id name created_time image_id image_width image_height
public class Image {
String id;
Integer width;
Integer height;
}
@Entity
public class User {

@PrimaryKey(autoGenerate = true)
private Long id;
String name;


@Embedded(prefix = "image_")
private Image image;
@ColumnInfo(name = "created_time")
private long createdTime;
Entity - TypeConverter
public class User {
@PrimaryKey
private Long id;
@TypeConverters(Converters.class)
private Date date;
public class Converters {
@TypeConverter
public static Date toDate(Long timestamp) {
return timestamp == null ? null : 

new Date(timestamp);
}
@TypeConverter
public static Long toTimestamp(Date date) {
return date == null ? null : date.getTime();
}
}
Entity - Relation
@Entity(indices = {@Index(value = "id", unique = true)}, 

foreignKeys = {
@ForeignKey(entity = Book.class, 

parentColumns = "id", 

childColumns = "bookId", 

onDelete = ForeignKey.CASCADE)
})
public class User {
@PrimaryKey(autoGenerate = true)
private Long id;
public Long bookId;

}
public class UserDao_Impl implements UserDao {
private final RoomDatabase __db;
private final EntityInsertionAdapter __insertionAdapterOfUser;
private final EntityDeletionOrUpdateAdapter __deletionAdapterOfUser;
private final EntityDeletionOrUpdateAdapter __updateAdapterOfUser;
public UserDao_Impl(RoomDatabase __db) {
this.__db = __db;
this.__insertionAdapterOfUser = new EntityInsertionAdapter<User>(__db) {
@Override
public String createQuery() {
return "INSERT OR REPLACE INTO
`User`(`id`,`name`,`created_time`,`updated_time`,`age`,`bookId`,`image_id`,`image_width`,`image_height`) VALUES
(?,?,?,?,?,?,?,?,?)";
}
@Override
public void bind(SupportSQLiteStatement stmt, User value) {
if (value.getId() == null) {
stmt.bindNull(1);
} else {
stmt.bindLong(1, value.getId());
}
if (value.getName() == null) {
stmt.bindNull(2);
} else {
stmt.bindString(2, value.getName());
}
stmt.bindLong(3, value.getCreatedTime());
if (value.getUpdatedTime() == null) {
stmt.bindNull(4);
} else {
stmt.bindLong(4, value.getUpdatedTime());
}
Error
@Query("SELECT * FROM users”)

List<User> getAll();
Architecture Components
• Handling Lifecycles

• LiveData

• ViewModel

• Room
• RxJava

• greenDAO ( Realm)

• MVP

• Firebase, Retrofit, Dagger, ButterKnife, Fresco, Glide, Mockito …
Android Lifecycle Components 

vs 

ReactiveX
public class TestActivity extends RxFragmentActivity {
@Override
protected void onCreate(@Nullable Bundle b) {
super.onCreate(savedInstanceState);
lifecycle()
.filter(e -> e == ActivityEvent.START)
.subscribe(e -> {
// on start
});
}
}
public class TestActivity extends LifecycleActivity
implements LifecycleObserver {
@Override
protected void onCreate(@Nullable Bundle b) {
super.onCreate(savedInstanceState);
getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// on start
}
}
LifecycleOwner RxLifecycle
public abstract class RxFragmentActivity
extends FragmentActivity
implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject
= BehaviorSubject.create();
@Override
@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.asObservable();
}
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
}
public class LifecycleActivity extends FragmentActivity
implements LifecycleRegistryOwner {
private final LifecycleRegistry mRegistry
= new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return mRegistry;
}
}
LifecycleActivity RxFragmentActivity
public class TestActivity extends RxFragmentActivity {
@Override
protected void onCreate(@Nullable Bundle b) {
super.onCreate(savedInstanceState);
Flowable<Long> data = getData();
data.compose(RxLifecycle.bindUntilEvent(
lifecycle(), ActivityEvent.DESTROY))
.subscribe(d -> {
// update ui
});
}
}
public class TestActivity extends LifecycleActivity {
@Override
protected void onCreate(@Nullable Bundle b) {
super.onCreate(savedInstanceState);
LiveData<Long> data = getData();
data.observe(this, result -> {
// update ui
});
}
}
LiveData RxFlowable
Don’t migrate from RxJava
But be sure that you correctly handle lifecycle.

”
“
Room vs greenDAO vs Realm
@Entity
public class RoomUser {
@PrimaryKey
private long id;
// getter & setter
}
Room
greenDAO
Realm
@Entity
public class GreenUser {
@Id
private long id;
// getter & setter
}
public class RealmUser extends RealmObject {
@PrimaryKey
private long id;
// getter & setter
}
@Entity(tableName = "user")
public class RoomUser {
@ColumnInfo(name = “first_name")
private String firstName;
}
@Entity(nameInDb = "user")
public class GreenUser {
@Property(nameInDb = “first_name")
private String firstName;
}
Room
greenDAO
Realm
@Entity(indices = @Index(“address"))
public class RoomUser {
private String address;
@Ignore
private String sessionId;
}
@Entity(indexes = @Index("address DESC"))
public class GreenUser {
private String address;
@Transient
private String sessionId;
}
public class RealmUser extends RealmObject {
@Index
private String address;
@Ignore
private String sessionId;
}
Room
greenDAO
Realm
@Dao
public interface RoomUserDao {
@Query("SELECT * FROM RoomUser WHERE id > 10 ORDER BY id DESC”)
List<RoomUser> getUsers();
}
public class GreenUseCase {
public List<GreenUser> getUsers() {
// get DaoSession
return new daoSession.getGreenUserDao().queryBuilder()
.where(GreenUserDao.Properties.Id.gt(10))
.orderDesc(GreenUserDao.Properties.Id)
.list();
}
}
public class RealmUseCase {
public RealmResults<RealmUser> getUsers() {
// get realm instance
return realm.where(RealmUser.class)
.greaterThan("id", 10)
.findAllSorted("id", Sort.DESCENDING);
}
}
Room
greenDAO
Realm
public class AndroidUser {

private String userId;



private String groupID;

}
public class AndroidGroup {



private String groupId;



private String groupName;



private List<AndroidUser> roomUser;

}
Relation
@Entity
public class RoomGroup {
@PrimaryKey
private long id;
}
@Entity(foreignKeys = @ForeignKey(
entity = RoomGroup.class,
parentColumns = "id",
childColumns = "groupId"))
public class RoomUser {
@PrimaryKey
private long id;
private long groupId;
}
https://developer.android.com/topic/libraries/architecture/room.html#no-object-references
Relation - Room
@Dao
public interface RoomGroupDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertGroup(RoomGroup group);
@Query("SELECT * FROM RoomGroup WHERE id = :id")
LiveData<RoomGroup> getGroup(long id);
}
@Dao
public interface RoomUserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertUsers(List<RoomUser> users);
@Query("SELECT * FROM RoomUser WHERE groupId = :groupId")
LiveData<List<RoomUser>> getUsers(long groupId);
}
@Entity
public class GreenGroup {
@Id
private long id;
@ToMany(referencedJoinProperty
= "groupId")
private List<GreenUser> users;
}
@Entity
public class GreenUser {
@Id
private long id;
private long groupId;
}
Relation - greenDAO
public class GreenUseCase {
public void insertGroup(GreenGroup group) {
daoSession.getGreenGroupDao()
.insertOrReplace(group);
daoSession.getGreenUserDao()
.insertOrReplaceInTx(group.getUsers());
}
public GreenGroup getGroup(long groupId) {
return daoSession.getGreenGroupDao()
.queryBuilder()
.where(GreenGroupDao.Properties.Id.eq(groupId))
.build()
.unique();
}
}
public class RealmGroup extends RealmObject {
@PrimaryKey
private long id;
RealmList<RealmUser> users;
}
public class RealmUser extends RealmObject {
@PrimaryKey
private long id;
}
Relation - Realm
public class RealmUseCase {
public void insertGroup(RealmGroup group) {
realm.insertOrUpdate(group);
}
public RealmGroup getGroup(long groupId) {
return realm.where(RealmGroup.class)
.equalTo("id", groupId)
.findFirst();
}
}
Realm GreenDao Room
Core Native Library SQLite SQLite
Performance Realm Realm
Relation


.
QueryBuilder X
DeepInsert X X
LazyLoading X
Integration Rx Rx, LiveData, Cursor
https://youtu.be/FrteWKKVyzI
https://youtu.be/bEKNi1JOrNs
https://youtu.be/MfHsPGQ6bgE
https://developer.android.com/topic/libraries/architecture/index.html
alpaca@vcnc.co.kr
• http://engineering.vcnc.co.kr/jobs/

More Related Content

What's hot

What's in the Latest Java
What's in the Latest JavaWhat's in the Latest Java
What's in the Latest Java
Serhii Voronin
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture Components
BurhanuddinRashid
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTruls Jørgensen
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
DataArt
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
Knoldus Inc.
 
CDI 2.0 Deep Dive
CDI 2.0 Deep DiveCDI 2.0 Deep Dive
CDI 2.0 Deep Dive
Thorben Janssen
 
Android Architecture - Khoa Tran
Android Architecture -  Khoa TranAndroid Architecture -  Khoa Tran
Android Architecture - Khoa Tran
Tu Le Dinh
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xTatsuya Maki
 
Spock
SpockSpock
Advanced Akka For Architects
Advanced Akka For ArchitectsAdvanced Akka For Architects
Advanced Akka For Architects
Lightbend
 
SolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
SolrJ: Power and Pitfalls - Jason Gerlowski, LucidworksSolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
SolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
Lucidworks
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Ryosuke Uchitate
 
SQLite 周りのテストをしよう
SQLite 周りのテストをしようSQLite 周りのテストをしよう
SQLite 周りのテストをしよう
ussy
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
Tiago de Freitas Lima
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentation
mrmean
 
Accessibility Testing using Axe
Accessibility Testing using AxeAccessibility Testing using Axe
Accessibility Testing using Axe
RapidValue
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEM
Jan Wloka
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
Jan Wloka
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
codepitbull
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guide
Mert Can Akkan
 

What's hot (20)

What's in the Latest Java
What's in the Latest JavaWhat's in the Latest Java
What's in the Latest Java
 
Android Architecture Components
Android Architecture ComponentsAndroid Architecture Components
Android Architecture Components
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinner
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
CDI 2.0 Deep Dive
CDI 2.0 Deep DiveCDI 2.0 Deep Dive
CDI 2.0 Deep Dive
 
Android Architecture - Khoa Tran
Android Architecture -  Khoa TranAndroid Architecture -  Khoa Tran
Android Architecture - Khoa Tran
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.x
 
Spock
SpockSpock
Spock
 
Advanced Akka For Architects
Advanced Akka For ArchitectsAdvanced Akka For Architects
Advanced Akka For Architects
 
SolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
SolrJ: Power and Pitfalls - Jason Gerlowski, LucidworksSolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
SolrJ: Power and Pitfalls - Jason Gerlowski, Lucidworks
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
SQLite 周りのテストをしよう
SQLite 周りのテストをしようSQLite 周りのテストをしよう
SQLite 周りのテストをしよう
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentation
 
Accessibility Testing using Axe
Accessibility Testing using AxeAccessibility Testing using Axe
Accessibility Testing using Axe
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEM
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guide
 

Similar to Architecture Components

Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta Indonesia
Pratama Nur Wijaya
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
Constantine Mars
 
Android Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, VonageAndroid Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, Vonage
DroidConTLV
 
Android Architecture Components with Kotlin
Android Architecture Components with KotlinAndroid Architecture Components with Kotlin
Android Architecture Components with Kotlin
Adit Lal
 
Presentation Android Architecture Components
Presentation Android Architecture ComponentsPresentation Android Architecture Components
Presentation Android Architecture Components
Attract Group
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
Matt Raible
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
Washington Botelho
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
Shem Magnezi
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
Rodrigo de Souza Castro
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Red Hat Developers
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
Hassan Abid
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developers
Anton Udovychenko
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2
Matt Raible
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
Ignacio Coloma
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
scalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
Ngoc Dao
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
koji lin
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - Italy
Yahoo
 

Similar to Architecture Components (20)

Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta Indonesia
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Android Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, VonageAndroid Architecture Components - Guy Bar on, Vonage
Android Architecture Components - Guy Bar on, Vonage
 
Android Architecture Components with Kotlin
Android Architecture Components with KotlinAndroid Architecture Components with Kotlin
Android Architecture Components with Kotlin
 
Presentation Android Architecture Components
Presentation Android Architecture ComponentsPresentation Android Architecture Components
Presentation Android Architecture Components
 
What's Coming in Spring 3.0
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developers
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - Italy
 

Recently uploaded

SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 

Recently uploaded (20)

SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 

Architecture Components

  • 3. Architecture Components • Google I/O 2017 
 Architecture Components - Introduction
 Architecture Components - Solving the Lifecycle
 Architecture Components - Persistence and Offline • • https://developer.android.com/topic/libraries/architecture/ index.html
  • 4. Architecture Components • Handling Lifecycles • LiveData • ViewModel • Room
  • 5. build.gradle • allprojects {
 repositories {
 jcenter()
 maven { url 'https://maven.google.com' }
 }
 } • compile "android.arch.lifecycle:runtime:1.0.0-alpha3"
 compile "android.arch.lifecycle:extensions:1.0.0-alpha3"
 annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha3"
 • compile "android.arch.persistence.room:runtime:1.0.0-alpha3"
 annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha3"
 • compile "android.arch.persistence.room:rxjava2:1.0.0-alpha3"
 testCompile "android.arch.persistence.room:testing:1.0.0-alpha3"
  • 7. public class MyActivity extends AppCompatActivity { private TestListener testListener; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); testListener = new TestListener(); } @Override protected void onStart() { super.onStart(); testListener.start(); } @Override protected void onStop() { super.onStop(); testListener.stop(); } }
  • 8. public class MyActivity extends AppCompatActivity { private TestListener testListener; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); testListener = new TestListener(); } @Override protected void onStart() { super.onStart(); testListener.start(); } @Override protected void onStop() { super.onStop(); testListener.stop(); } } onStart 
 Override .
  • 10. Handling Lifecycles • Lifecycle • LifecycleOwner • LifecycleObserver
  • 11. public class MyActivity extends LifecycleActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lifecycle); TestListener testListener = new TestListener(
 getLifecycle(), 
 result -> { // update UI }); } }
  • 12. public class TestListener implements LifecycleObserver { private Lifecycle lifecycle; public TestListener(Lifecycle lifecycle, TestCallback callback) { lifecycle.addObserver(this); this.lifecycle = lifecycle; } @OnLifecycleEvent(Lifecycle.Event.ON_START) void start() { // start Event } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) void clean() { lifecycle.removeObserver(this); } }
  • 13. public class MyActivity extends CustomActivity { @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 } }
  • 14. public class LifecycleActivity extends FragmentActivity 
 implements LifecycleRegistryOwner { private final LifecycleRegistry mRegistry 
 = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return mRegistry; } }
  • 15. public class MyActivity extends CustomActivity implements LifecycleRegistryOwner { private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return lifecycleRegistry; } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lifecycle); TestListener testListener = new TestListener(getLifecycle(), state -> { // update Ui }); } }
  • 16.
  • 17. public class MyActivity extends LifecycleActivity { private TestListener testListener; @Override protected void onStart() { super.onStart(); Utils.checkUserStatus(state -> { if (state.equals("OK")) { testListener.start(); } }); }
  • 18. public class MyActivity extends LifecycleActivity { private TestListener testListener; @Override protected void onStart() { super.onStart(); // ? Utils.checkUserStatus(state -> { if (state.equals("OK")) { testListener.start(); } }); }
  • 19. StartCreate Resume Pause Stop Destroy testListener.stop Utils.checkStatus testListener.start
  • 21. public class MyActivity extends LifecycleActivity { private TestListener testListener; @Override protected void onStart() { super.onStart(); Utils.checkUserStatus(state -> { if (state.equals("OK") && getLifecycle()
 .getCurrentState()
 .isAtLeast(Lifecycle.State.STARTED)) { testListener.start(); } }); }
  • 23. LiveData • Observable Data Holder • Lifecycle aware • Automatic subscription management
  • 24. LiveData<String> stateData = new MutableLiveData<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); stateData.observe((LifecycleOwner) this, ((String) result) -> { // stateData . }); } @Override protected void onStart() { super.onStart(); stateData.setValue(“Start"); }
  • 25. public class StateChangeLiveData extends MutableLiveData<String> { @Override protected void onActive() { super.onActive();
 // Active Observer 
 // Active: Lifecycle.State STARTED RESUMED } @Override protected void onInactive() { super.onInactive();
 // Active Observer } }
  • 27. public class MyActivity extends LifecycleActivity { LiveData<User> userData; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); userData = userRepository.fetchData(); userData.observe(this, user -> { // update UI }); } }
  • 28. StartCreate Resume Pause Stop Destroy Rotated fetchData StartCreate Resume fetchData
  • 30. ViewModel The ViewModel class is designed to store and manage UI-related data so that the data survives configuration changes such as screen rotations. ” “
  • 31. public class UserViewModel extends ViewModel { }
 
 public class UserViewModel extends AndroidViewModel {
 // Application ViewModel
 }
  • 33. public class MyActivity extends LifecycleActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.insert_activity); 
 // ViewModelStore ViewModel . UserListViewModel viewModel = ViewModelProviders.of(this)
 .get(UserListViewModel.class);
  • 34. public class MyActivity extends LifecycleActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewModelProviders.of(this).get(UserListViewModel.class) .getData() .observe(this, user -> { //update UI }); public class UserListViewModel extends ViewModel {
 private LiveData<User> userLiveData;
 
 public LiveData<User> getData() {
 if (userLiveData == null) {
 userLiveData = userRepository.fetchData();
 }
 return userLiveData;
 }
 }
  • 35. StartCreate Resume Pause Stop Destroy Rotated fetchData StartCreate Resume fetchData
  • 36. StartCreate Resume Pause Stop Destroy Rotated StartCreate Resume ViewModel fetchData getData getData
  • 37. Room
  • 38. Room • Sqlite ORM • Entity • Dao • Database
  • 39. id name create_time @Entity public class User { @PrimaryKey(autoGenerate = true) private Long id; String name; @ColumnInfo(name = "created_time") private long createdTime; @Ignore Bitmap profile; } Entity
  • 40. DAO @Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE id IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE name LIKE :first LIMIT 1") User findByName(String first); @Insert(onConflict = OnConflictStrategy.REPLACE) void insertAll(User... users); @Delete void delete(User user); @Update void updateUser(User user);
  • 41. DAO (Rx, LiveData) @Query("SELECT * FROM user") LiveData<List<User>> getAllSync(); @Query("SELECT * FROM user WHERE id = :userId") LiveData<User> fetchUser(String userId); @Query("SELECT * from user where id = :id LIMIT 1") Flowable<User> loadUserByIdRx(int id); @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5") Cursor loadRawUsersOlderThan(int minAge);
  • 42. Database @Database(entities = {User.class, Book.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { 
 public abstract UserDao userDao(); public abstract BookDao bookDao(); }
  • 43. Entity - Embedded id name created_time image_id image_width image_height public class Image { String id; Integer width; Integer height; } @Entity public class User {
 @PrimaryKey(autoGenerate = true) private Long id; String name; 
 @Embedded(prefix = "image_") private Image image; @ColumnInfo(name = "created_time") private long createdTime;
  • 44. Entity - TypeConverter public class User { @PrimaryKey private Long id; @TypeConverters(Converters.class) private Date date; public class Converters { @TypeConverter public static Date toDate(Long timestamp) { return timestamp == null ? null : 
 new Date(timestamp); } @TypeConverter public static Long toTimestamp(Date date) { return date == null ? null : date.getTime(); } }
  • 45. Entity - Relation @Entity(indices = {@Index(value = "id", unique = true)}, 
 foreignKeys = { @ForeignKey(entity = Book.class, 
 parentColumns = "id", 
 childColumns = "bookId", 
 onDelete = ForeignKey.CASCADE) }) public class User { @PrimaryKey(autoGenerate = true) private Long id; public Long bookId;
 }
  • 46. public class UserDao_Impl implements UserDao { private final RoomDatabase __db; private final EntityInsertionAdapter __insertionAdapterOfUser; private final EntityDeletionOrUpdateAdapter __deletionAdapterOfUser; private final EntityDeletionOrUpdateAdapter __updateAdapterOfUser; public UserDao_Impl(RoomDatabase __db) { this.__db = __db; this.__insertionAdapterOfUser = new EntityInsertionAdapter<User>(__db) { @Override public String createQuery() { return "INSERT OR REPLACE INTO `User`(`id`,`name`,`created_time`,`updated_time`,`age`,`bookId`,`image_id`,`image_width`,`image_height`) VALUES (?,?,?,?,?,?,?,?,?)"; } @Override public void bind(SupportSQLiteStatement stmt, User value) { if (value.getId() == null) { stmt.bindNull(1); } else { stmt.bindLong(1, value.getId()); } if (value.getName() == null) { stmt.bindNull(2); } else { stmt.bindString(2, value.getName()); } stmt.bindLong(3, value.getCreatedTime()); if (value.getUpdatedTime() == null) { stmt.bindNull(4); } else { stmt.bindLong(4, value.getUpdatedTime()); }
  • 47. Error @Query("SELECT * FROM users”)
 List<User> getAll();
  • 48. Architecture Components • Handling Lifecycles • LiveData • ViewModel • Room
  • 49. • RxJava • greenDAO ( Realm) • MVP • Firebase, Retrofit, Dagger, ButterKnife, Fresco, Glide, Mockito …
  • 50. Android Lifecycle Components 
 vs 
 ReactiveX
  • 51. public class TestActivity extends RxFragmentActivity { @Override protected void onCreate(@Nullable Bundle b) { super.onCreate(savedInstanceState); lifecycle() .filter(e -> e == ActivityEvent.START) .subscribe(e -> { // on start }); } } public class TestActivity extends LifecycleActivity implements LifecycleObserver { @Override protected void onCreate(@Nullable Bundle b) { super.onCreate(savedInstanceState); getLifecycle().addObserver(this); } @OnLifecycleEvent(Lifecycle.Event.ON_START) void start() { // on start } } LifecycleOwner RxLifecycle
  • 52. public abstract class RxFragmentActivity extends FragmentActivity implements LifecycleProvider<ActivityEvent> { private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create(); @Override @NonNull @CheckResult public final Observable<ActivityEvent> lifecycle() { return lifecycleSubject.asObservable(); } @Override @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); lifecycleSubject.onNext(ActivityEvent.CREATE); } @Override @CallSuper protected void onStart() { super.onStart(); lifecycleSubject.onNext(ActivityEvent.START); } } public class LifecycleActivity extends FragmentActivity implements LifecycleRegistryOwner { private final LifecycleRegistry mRegistry = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return mRegistry; } } LifecycleActivity RxFragmentActivity
  • 53. public class TestActivity extends RxFragmentActivity { @Override protected void onCreate(@Nullable Bundle b) { super.onCreate(savedInstanceState); Flowable<Long> data = getData(); data.compose(RxLifecycle.bindUntilEvent( lifecycle(), ActivityEvent.DESTROY)) .subscribe(d -> { // update ui }); } } public class TestActivity extends LifecycleActivity { @Override protected void onCreate(@Nullable Bundle b) { super.onCreate(savedInstanceState); LiveData<Long> data = getData(); data.observe(this, result -> { // update ui }); } } LiveData RxFlowable
  • 54. Don’t migrate from RxJava But be sure that you correctly handle lifecycle.
 ” “
  • 55. Room vs greenDAO vs Realm
  • 56. @Entity public class RoomUser { @PrimaryKey private long id; // getter & setter } Room greenDAO Realm @Entity public class GreenUser { @Id private long id; // getter & setter } public class RealmUser extends RealmObject { @PrimaryKey private long id; // getter & setter }
  • 57. @Entity(tableName = "user") public class RoomUser { @ColumnInfo(name = “first_name") private String firstName; } @Entity(nameInDb = "user") public class GreenUser { @Property(nameInDb = “first_name") private String firstName; } Room greenDAO Realm
  • 58. @Entity(indices = @Index(“address")) public class RoomUser { private String address; @Ignore private String sessionId; } @Entity(indexes = @Index("address DESC")) public class GreenUser { private String address; @Transient private String sessionId; } public class RealmUser extends RealmObject { @Index private String address; @Ignore private String sessionId; } Room greenDAO Realm
  • 59. @Dao public interface RoomUserDao { @Query("SELECT * FROM RoomUser WHERE id > 10 ORDER BY id DESC”) List<RoomUser> getUsers(); } public class GreenUseCase { public List<GreenUser> getUsers() { // get DaoSession return new daoSession.getGreenUserDao().queryBuilder() .where(GreenUserDao.Properties.Id.gt(10)) .orderDesc(GreenUserDao.Properties.Id) .list(); } } public class RealmUseCase { public RealmResults<RealmUser> getUsers() { // get realm instance return realm.where(RealmUser.class) .greaterThan("id", 10) .findAllSorted("id", Sort.DESCENDING); } } Room greenDAO Realm
  • 60. public class AndroidUser {
 private String userId;
 
 private String groupID;
 } public class AndroidGroup {
 
 private String groupId;
 
 private String groupName;
 
 private List<AndroidUser> roomUser;
 } Relation
  • 61. @Entity public class RoomGroup { @PrimaryKey private long id; } @Entity(foreignKeys = @ForeignKey( entity = RoomGroup.class, parentColumns = "id", childColumns = "groupId")) public class RoomUser { @PrimaryKey private long id; private long groupId; } https://developer.android.com/topic/libraries/architecture/room.html#no-object-references Relation - Room @Dao public interface RoomGroupDao { @Insert(onConflict = OnConflictStrategy.REPLACE) void insertGroup(RoomGroup group); @Query("SELECT * FROM RoomGroup WHERE id = :id") LiveData<RoomGroup> getGroup(long id); } @Dao public interface RoomUserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) void insertUsers(List<RoomUser> users); @Query("SELECT * FROM RoomUser WHERE groupId = :groupId") LiveData<List<RoomUser>> getUsers(long groupId); }
  • 62. @Entity public class GreenGroup { @Id private long id; @ToMany(referencedJoinProperty = "groupId") private List<GreenUser> users; } @Entity public class GreenUser { @Id private long id; private long groupId; } Relation - greenDAO public class GreenUseCase { public void insertGroup(GreenGroup group) { daoSession.getGreenGroupDao() .insertOrReplace(group); daoSession.getGreenUserDao() .insertOrReplaceInTx(group.getUsers()); } public GreenGroup getGroup(long groupId) { return daoSession.getGreenGroupDao() .queryBuilder() .where(GreenGroupDao.Properties.Id.eq(groupId)) .build() .unique(); } }
  • 63. public class RealmGroup extends RealmObject { @PrimaryKey private long id; RealmList<RealmUser> users; } public class RealmUser extends RealmObject { @PrimaryKey private long id; } Relation - Realm public class RealmUseCase { public void insertGroup(RealmGroup group) { realm.insertOrUpdate(group); } public RealmGroup getGroup(long groupId) { return realm.where(RealmGroup.class) .equalTo("id", groupId) .findFirst(); } }
  • 64. Realm GreenDao Room Core Native Library SQLite SQLite Performance Realm Realm Relation 
 . QueryBuilder X DeepInsert X X LazyLoading X Integration Rx Rx, LiveData, Cursor