Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Android Architecture Components - Guy Bar on, Vonage

256 views

Published on

As presented in Droidcon Tel Aviv 2017:
http://il.droidcon.com

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Android Architecture Components - Guy Bar on, Vonage

  1. 1. Android Architecture Components Guy Baron, Director Mobile @ Vonage DroidCon TLV 2017
  2. 2. Backend SQLite DB UI Users Retrofit Boilerplate! Lifecycle? MVP ? MVVM ?
  3. 3. Android Architecture Components Make it easier and more fun to write robust apps, empowering developers to focus on areas where they can innovate. Issues like complex lifecycles and the lack of a recommended app architecture make it challenging to write robust apps.
  4. 4. https://developer.android.com/topic/libraries/architecture/guide.html
  5. 5. App Architecture Concepts Abstraction layer over SQLite ● Room - light ORM library ● Allows fluent database access Repository ● Responsible for handling data operations. ● Knows where to get the data from and what API calls to make when data is updated
  6. 6. Room @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract List<User> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
  7. 7. App Architecture Concepts LiveData ● LiveData is an observable lifecycle- aware data holder class
  8. 8. Room & LiveData @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract LiveData<List<User>> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
  9. 9. App Architecture Concepts ViewModel ● Stores UI-related data in a lifecycle conscious way Lifecycle-aware components ● LifecycleOwner / LifecycleObserver
  10. 10. Room & LiveData & ViewModel @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract LiveData<List<User>> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); } class MyViewModel extends ViewModel { public final LiveData<List<User>> usersList; public MyViewModel() { AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build(); usersList = db.userDao().usersByLastName(); } }
  11. 11. Room & LiveData & ViewModel & UI @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract LiveData<List<User>> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); } class MyViewModel extends ViewModel { public final LiveData<List<User>> usersList; public MyViewModel() { AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build(); usersList = db.userDao().usersByLastName(); } } class MyActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedState) { super.onCreate(savedState); MyViewModel viewModel = ViewModelProviders.of(this) .get(MyViewModel.class); // ... } }
  12. 12. Data Flow Room Use Room to store the new data in the SQLite database for offline use ViewModel Store the data in a ViewModel object to make it accessible for UI objects BE Service Use the Retrofit library to access your backend and fetch for data LiveData Use Room to fetch data from the SQLite database and get LiveData objects UI Activities access the data using the ViewModel. They observe and respond to changes
  13. 13. Backend SQLite DB UI Users Retrofit Room Lifecycle LiveData ViewModel
  14. 14. One more thing… Paging
  15. 15. Why paging is interesting ● We use SQLiteCursor for fetching data from the database ● SQLiteCursor uses a CursorWindow, a buffer of rows typically 2MB in size ● Challenges: ○ SQLiteCursor doesn’t hold any database transaction open ○ SQLiteCursor.getCount() scans entire query ○ SQLiteCursor does not know data has changed
  16. 16. SQLiteCursor doesn’t hold any database transaction open cursor.moveToPosition(position);
  17. 17. SQLiteCursor doesn’t hold any database transaction open cursor.moveToNext();
  18. 18. SQLiteCursor.getCount() scans entire query cursor.getCount();
  19. 19. The Paging library ● Uses small queries ● Queries that fit within a single CursorWindow
  20. 20. Paging flows
  21. 21. Room & LiveData & ViewModel & UI & Paging @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract LiveData<List<User>> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
  22. 22. Room & LiveData & ViewModel & UI & Paging @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract DataSource.Factory<Integer, User> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
  23. 23. Room & LiveData & ViewModel & UI & Paging @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract DataSource.Factory<Integer, User> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); } class MyViewModel extends ViewModel { LiveData<List<User>> usersList; public MyViewModel() { AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build(); usersList = db.userDao().usersByLastName(); } }
  24. 24. Room & LiveData & ViewModel & UI & Paging @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract DataSource.Factory<Integer, User> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); } class MyViewModel extends ViewModel { LiveData<PagedList<User>> usersList; public MyViewModel() { AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build(); usersList = new LivePagedListBuilder<>( db.userDao.usersByLastName(),20).build(); } }
  25. 25. Room & LiveData & ViewModel & UI & Paging @Entity class User { private @PrimaryKey int uid; private @ColumnInfo(name = "first_name") String firstName; } @Dao interface UserDao { @Query("SELECT * FROM user ORDER BY first_name ASC") public abstract DataSource.Factory<Integer, User> usersByLastName(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); } class MyViewModel extends ViewModel { LiveData<PagedList<User>> usersList; public MyViewModel() { AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build(); usersList = new LivePagedListBuilder<>( db.userDao.usersByLastName(),20).build(); } } class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedState) { super.onCreate(savedState); MyViewModel viewModel = ViewModelProviders.of(this). get(MyViewModel.class); viewModel.usersList.observe(this, new Observer<PagedList<User>>() { void onChanged(PagedList<User> users) { adapter.setList(users); } }); }
  26. 26. Thank you

×