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

332 views

Published on

An introduction to Android Architecture components: lifecycle, room, viewModel, livedata and paging. A way to embrace our Android application

Published in: Software
  • Be the first to comment

  • Be the first to like this

Android Architecture components

  1. 1. GDG DevFest Mediterranean 2017 Cap. II Mike Trizio @mik3lantoni0 #nerdipity
  2. 2. Mike Trizio - @mik3lantoni0 - #nerdipity Michelantonio Trizio GDG Bari community lead Computer Science Engineer Android Dev CTO @ Wideverse
  3. 3. Mike Trizio - @mik3lantoni0 - #nerdipity SPOILER ALERT
  4. 4. Mike Trizio - @mik3lantoni0 - #nerdipity About architecture components ➔ Announced at Google I/O 2017 ➔ Provide frameworks to create more maintainable and robust app ➔ Encourage decoupled components within the app
  5. 5. Mike Trizio - @mik3lantoni0 - #nerdipity What’s the problem?
  6. 6. Mike Trizio - @mik3lantoni0 - #nerdipity The solution Follow architectural principle ➔ Separation of concerns ➔ Drive your UI from a model (preferably persistent one)
  7. 7. Mike Trizio - @mik3lantoni0 - #nerdipity App architecture
  8. 8. Mike Trizio - @mik3lantoni0 - #nerdipity SEASON 1 1x01 - Room 1x02 - Lifecycle 1x03 - ViewModel 1x04 - LiveData 1x05 - Paging
  9. 9. Mike Trizio - @mik3lantoni0 - #nerdipity 1x01 - Room
  10. 10. Mike Trizio - @mik3lantoni0 - #nerdipity Data layer before Room
  11. 11. Mike Trizio - @mik3lantoni0 - #nerdipity Room architecture diagram
  12. 12. Mike Trizio - @mik3lantoni0 - #nerdipity Components of room @Entity: annotation needed define a table @Dao: annotation needed define a Data Access Object @Database: annotation to create the database holder
  13. 13. Mike Trizio - @mik3lantoni0 - #nerdipity Create an entity @Entity(tableName = "characters") class Character { @PrimaryKey (autoGenerate = true) public int id; public String firstName; public String lastName; @Ignore // Tells Room to ignore this field Bitmap picture; } id (PK) firstName LastName 1 Walter White 2 Jesse Pinkman 3 Gustavo Fring character table
  14. 14. Mike Trizio - @mik3lantoni0 - #nerdipity Create a Dao Annotations available @Dao @Insert @Delete @Update @Query @Dao // Required annotation for Dao to be recognized by Room public interface CharacterDao { // Returns a list of all users in the db @Query("SELECT * FROM characters") List<User> getAll(); // Inserts multiple users @Insert void insertAll(Character... characters); // Deletes a single character @Delete void delete(Character character); }
  15. 15. Mike Trizio - @mik3lantoni0 - #nerdipity Create the Database @Database(entities = {Character.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { private static AppDatabase sInstance; public abstract CharacterDao characterDao(); //Getters for Dao public static AppDatabase getInstance(Context context) { if (sInstance == null) { sInstance = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build(); } return sInstance; } }
  16. 16. Mike Trizio - @mik3lantoni0 - #nerdipity Query examples (1) @Query("SELECT * FROM character WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1") Character findByName(String first, String last); @Query("SELECT series.id, series.title, series.description, category.name as categoryName FROM series LEFT JOIN category ON series.category_id = category.id") List<CategorySerie> getCategorySeries();
  17. 17. Mike Trizio - @mik3lantoni0 - #nerdipity Query examples (2) @Query("SELECT series.id, series.title, series.description, category.name as categoryName FROM series LEFT JOIN category ON series.category_id = category.id where series.id = :seriesId") CategorySerie getCategorySerie(long seriesId);
  18. 18. Mike Trizio - @mik3lantoni0 - #nerdipity get and use Database instance //GET DATABASE INSTANCE AppDatabase database = AppDatabase.getInstance(Context context); //GET ALL CHARACTERS INTO THE DB List<Character> allCharacters = database.characterDao().getAll();
  19. 19. Mike Trizio - @mik3lantoni0 - #nerdipity Migration (1) @Database(entities = {Character.class}, version = 2) //update the version public abstract class AppDatabase extends RoomDatabase { private static SunshineDatabase sInstance; public abstract CharacterDao characterDao(); public static AppDatabase getInstance(Context context) { if (sInstance == null) { sInstance = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build(); } return sInstance; } }
  20. 20. Mike Trizio - @mik3lantoni0 - #nerdipity Migration (2) @Entity(tableName = "character") class Character { @PrimaryKey (autoGenerate = true) public int id; public String firstName; public String lastName; public String alias; //add the alias field @Ignore // Tells Room to ignore this field Bitmap picture; }
  21. 21. Mike Trizio - @mik3lantoni0 - #nerdipity Migration (3) Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name").addMigrations(MIGRATION_1_2).build(); static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE character add column alias text"); } }
  22. 22. Mike Trizio - @mik3lantoni0 - #nerdipity 1x02 - Lifecycle
  23. 23. Mike Trizio - @mik3lantoni0 - #nerdipity Android activity lifecycle
  24. 24. Mike Trizio - @mik3lantoni0 - #nerdipity going upside down... or simply rotate the phone
  25. 25. Mike Trizio - @mik3lantoni0 - #nerdipity ...a lot of stranger things can happen
  26. 26. Mike Trizio - @mik3lantoni0 - #nerdipity public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume() { } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onPause() { } } aLifecycleOwner.getLifecycle().addObserver(new MyObserver()); Lifecycle observer implementation
  27. 27. Mike Trizio - @mik3lantoni0 - #nerdipity observable events ON_CREATE ON_DESTROY ON_PAUSE ON_RESUME ON_START ON_STOP
  28. 28. Mike Trizio - @mik3lantoni0 - #nerdipity LifecycleOwner public class MyActivity extends LifecycleActivity { private MyObeserver myObeserver; public void onCreate(...) { myObeserver = new MyObeserver(this, getLifecycle(), location ->{ // update UI }); } }
  29. 29. Mike Trizio - @mik3lantoni0 - #nerdipity 1x03 - ViewModel
  30. 30. Mike Trizio - @mik3lantoni0 - #nerdipity ViewModels persist configuration change
  31. 31. Mike Trizio - @mik3lantoni0 - #nerdipity Interaction of entities in an app built with Architecture components
  32. 32. Mike Trizio - @mik3lantoni0 - #nerdipity public class CharacterDetailViewModel extends ViewModel { private CharacterEntry mCharacter; public DetailActivityViewModel(CharacterDao dao, int characterId) { mCharacter = dao.getDetails(id); } public CharacterEntry getCharacter(){ return mCharacter; } } Create a viewModel (1)
  33. 33. Mike Trizio - @mik3lantoni0 - #nerdipity Create a viewModel (2) public class DetailActivity extends LifecycleActivity{ @Override protected void onCreate(Bundle savedInstanceState){ CharacterModelFactory characterFactory = new CharacterModelFactory(dao, characterId); characterViewModel = ViewModelProviders.of(this, characterModelFacotry).get(CharacterDetailViewModel.class); } }
  34. 34. Mike Trizio - @mik3lantoni0 - #nerdipity 1x04 - LiveData
  35. 35. Mike Trizio - @mik3lantoni0 - #nerdipity DING DING DING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  36. 36. Mike Trizio - @mik3lantoni0 - #nerdipity LiveData example MutableLiveData<String> name = new MutableLiveData<String>(); name.setValue("Saul"); name.observe(<LIFECYCLE OWNER>, newName -> { // Do something when the observer is triggered; usually updating the UI });
  37. 37. Mike Trizio - @mik3lantoni0 - #nerdipity merge liveData and viewModel public CharacterDetailViewModel(){ mCharacter = new MutableLiveData<>(); } mViewModel.getCharacter().observe( this, characterEntry -> { // Update the UI }); if (characterEntry != null) bindWeatherToUI(characterEntry);
  38. 38. Mike Trizio - @mik3lantoni0 - #nerdipity Add a new character live
  39. 39. Mike Trizio - @mik3lantoni0 - #nerdipity 1x05 - Paging
  40. 40. Mike Trizio - @mik3lantoni0 - #nerdipity when we deal with a lot of data….
  41. 41. Mike Trizio - @mik3lantoni0 - #nerdipity Paging library workflow (mainly in background)
  42. 42. Mike Trizio - @mik3lantoni0 - #nerdipity ➔ KeyDatasource ➔ TiledDataSource @Query("select * from users WHERE age > :age order by name DESC, id ASC") TiledDataSource<User> usersOlderThan(int age); Datasource
  43. 43. Mike Trizio - @mik3lantoni0 - #nerdipity PagedList ➔ Loads data from Datasource ➔ You can configure how much data is loaded and how much data should be prefetched ➔ Can provide update signals to other classes
  44. 44. Mike Trizio - @mik3lantoni0 - #nerdipity PagedListAdapter ➔ Implementation of RecyclerView.Adapter ➔ Presents data from PagedList ➔ use a background thread to compute changes from PagedList
  45. 45. Mike Trizio - @mik3lantoni0 - #nerdipity LivePagedListProvider @Query("SELECT * from users order WHERE age > :age order by name DESC, id ASC") public abstract LivePagedListProvider<Integer, User> usersOlderThan(int age);
  46. 46. Mike Trizio - @mik3lantoni0 - #nerdipity Recap 1. Room - provide simple interaction with database 2. Lifecycle - better dealing with Activity Lifecycle 3. ViewModel - way to hold and manage data 4. LiveData - data holder lifecycle aware that allow to observe data 5. Paging - easy and light way to load information as needed
  47. 47. Mike Trizio - @mik3lantoni0 - #nerdipity what’s next? Architecture components guide https://goo.gl/j5Zztk Architecture talk @ GDD Krakow 2017 https://goo.gl/6C2fvr Architecture guide codelab https://goo.gl/gF9Vyu
  48. 48. Mike Trizio - @mik3lantoni0 - #nerdipity That’s all folks!!!
  49. 49. Mike Trizio - @mik3lantoni0 - #nerdipity Questions?
  50. 50. Mike Trizio - @mik3lantoni0 - #nerdipity Thank you! Rate this talk please https://goo.gl/TDT5Hb Follow me @mik3lantoni0

×