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 with Kotlin

290 views

Published on

A small set of slides showing the usages and introducing the concept of the arch components library

Published in: Technology
  • Be the first to comment

Android Architecture Components with Kotlin

  1. 1. Kotlin and Android Arch Components Adit Lal @aditlal
  2. 2. Introduction An application with a solid architecture should be: •Easy to scale and maintain. •Each component should be isolated and decoupled. •Easy to test Kotlin and Android Arch Components
  3. 3. Kotlin and Android Arch Components
  4. 4. Components Create an UI that automatically responds to lifecycle events. Lifecycle Kotlin and Android Arch Components
  5. 5. Components Create an UI that automatically responds to lifecycle events. Lifecycle LiveData Build data objects that notify views when underlying data changes Kotlin and Android Arch Components
  6. 6. Components Create an UI that automatically responds to lifecycle events. Lifecycle LiveData ViewModel Build data objects that notify views when underlying data changes Store UI related data that isn’t destroyed on app rotation Kotlin and Android Arch Components
  7. 7. Components Create an UI that automatically responds to lifecycle events. Lifecycle LiveData ViewModel Room Build data objects that notify views when underlying data changes Store UI related data that isn’t destroyed on app rotation Access your data with the power of SQLite and safety of in-app objects. Kotlin and Android Arch Components
  8. 8. Lifecycle States and Events Kotlin and Android Arch Components
  9. 9. Kotlin and Android Arch Components Lifecycle
  10. 10. Kotlin and Android Arch Components Lifecycle
  11. 11. Kotlin and Android Arch Components
  12. 12. Kotlin and Android Arch Components /** * Displays a message when app comes to foreground and goes to background. */ class AppLifecycleObserver @Inject constructor(context: Context) : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { enterForegroundToast.showAfterCanceling(enterBackgroundToast) } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { enterBackgroundToast.showAfterCanceling(enterForegroundToast) } } Lifecycle
  13. 13. Kotlin and Android Arch Components class AppLifecycleObserver @Inject constructor(context: Context) : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { enterForegroundToast.showAfterCanceling(enterBackgroundToast) } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { enterBackgroundToast.showAfterCanceling(enterForegroundToast) } } Lifecycle ProcessLifecycleOwner.get().lifecycle.addObserver(appLifecycleObserver)
  14. 14. Kotlin and Android Arch Components /** * Displays a message when app comes to foreground and goes to background. */ class AppLifecycleObserver @Inject constructor(context: Context) : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { enterForegroundToast.showAfterCanceling(enterBackgroundToast) } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { enterBackgroundToast.showAfterCanceling(enterForegroundToast) } } Lifecycle
  15. 15. Kotlin and Android Arch Components /** * Displays a message when app comes to foreground and goes to background. */ class AppLifecycleObserver @Inject constructor(context: Context) : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { enterForegroundToast.showAfterCanceling(enterBackgroundToast) } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { enterBackgroundToast.showAfterCanceling(enterForegroundToast) } } Lifecycle
  16. 16. LiveData LiveData is an observable data holder. It lets the components in your app, usually the UI, observe data objects for changes. Kotlin and Android Arch Components
  17. 17. Kotlin and Android Arch Components LiveData
  18. 18. Kotlin and Android Arch Components LiveData
  19. 19. Kotlin and Android Arch Components LiveData
  20. 20. LiveData var userLiveData : MutableLiveData<List<User>> = MutableLiveData();
  21. 21. LiveData var userLiveData : MutableLiveData<List<User>> = MutableLiveData(); userLiveData.value = User(id=1, name="John Doe”)
  22. 22. LiveData var userLiveData : MutableLiveData<List<User>> = MutableLiveData(); userLiveData.value = User(id=1, name="John Doe”) //Activity or fragment viewModel.getUsers().observe( this, Observer { result -> run { //Handle Result } })
  23. 23. LiveData
  24. 24. ViewModel Observes the lifecycle state of the view, maintaining consistency during configuration changes and other Android lifecycle events. The ViewModel class is designed to store and manage UI-related data so that the data survives configuration changes such as screen rotations.  Kotlin and Android Arch Components
  25. 25. ViewModel
  26. 26. ViewModel
  27. 27. class NoteViewModel @Inject constructor(var repo: NotesRepository) : ViewModel() { fun getNotes(sort: String): LiveData<List<Note>> { return repo.getAllNotes(sort = sort) } fun addNote(note: Note): LiveData<Note> { return repo.addNote(note = note) } fun deleteNote(note: Note): LiveData<Int> { return repo.deleteNote(note) } ViewModel
  28. 28. class NoteViewModel @Inject constructor(var repo: NotesRepository) : ViewModel() { fun getNotes(sort: String): LiveData<List<Note>> { return repo.getAllNotes(sort = sort) } fun addNote(note: Note): LiveData<Note> { return repo.addNote(note = note) } fun deleteNote(note: Note): LiveData<Int> { return repo.deleteNote(note) } ViewModel
  29. 29. class NoteViewModel @Inject constructor(var repo: NotesRepository) : ViewModel() { fun getNotes(sort: String): LiveData<List<Note>> { return repo.getAllNotes(sort = sort) } fun addNote(note: Note): LiveData<Note> { return repo.addNote(note = note) } fun deleteNote(note: Note): LiveData<Int> { return repo.deleteNote(note) } ViewModel
  30. 30. class NotesListActivity : AppCompatActivity(){ private lateinit var notesList: ArrayList<Note> @Inject lateinit var viewModelFactory: ViewModelFactory private val viewModel by lazy { ViewModelProviders.of( this@NotesListActivity, viewModelFactory).get(NoteViewModel::class.java) } ... } ViewModel
  31. 31. ViewModel
  32. 32. @Inject lateinit var viewModelFactory: ViewModelFactory private val viewModel by lazy { ViewModelProviders.of(this@NotesListActivity, viewModelFactory).get(NoteViewModel::class.java) } //Activity viewModel.getNotes(sort = sort).observe( this, Observer { data -> run { notesList.clear() notesList.addAll(data!!) adapter.updateItems(notesList) } }) ViewModel
  33. 33. Room Persistence library for Android Kotlin and Android Arch Components
  34. 34. Entities and Dao’s Kotlin and Android Arch Components Room
  35. 35. @Entity(tableName = "user_table") data class User(var created: Date = Date(), var name: String = "", @PrimaryKey var id: Int = 0) Entities
  36. 36. interface BaseDao<T> { @Insert fun insert(vararg obj: T) } @Dao abstract class DataDao : BaseDao<Data>() { @Query("SELECT * FROM Data") abstract fun getData(): List<Data> } Dao
  37. 37. @Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(user: User) @Delete fun delete(user: User) @Query("SELECT * FROM user_table") fun getUsers(): List<User> } Dao
  38. 38. @Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(user: User) @Delete fun delete(user: User) @Query("SELECT * FROM user_table") fun getUsers(): List<User> } Dao
  39. 39. @Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(user: User) @Delete fun delete(user: User) @Query("SELECT * FROM user_table") fun getUsers(): LiveData<List<User>> } Dao
  40. 40. @Transaction open fun updateData(users: List<User>) { deleteAllUsers() insertAll(users) } Dao
  41. 41. class UserAndAllPets { @Embedded var user: User? = null @Relation(parentColumn = “userId”, entityColumn = “owner”) var pets: List<Pet> = ArrayList() } //UserDao.kt @Transaction @Query(“SELECT * FROM Users”) List<UserAndAllPets> getUsers(); Dao
  42. 42. @Database(entities = arrayOf(User::class), version = 1, exportSchema = true) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun UserDao(): UserDao } Database
  43. 43. class MyApp : Application() { lateinit var mDataBase: AppDatabase override fun onCreate() { super.onCreate() mDataBase = Room.databaseBuilder(this, AppDatabase::class.java, "users").build() } } Database
  44. 44. @Provides @Singleton fun provideDB(context: Context): AppDatabase = Room.databaseBuilder(context, AppDatabase::class.java, “users") .fallbackToDestructiveMigration() .build() Database
  45. 45. Paging Efficient Lists and data loading Kotlin and Android Arch Components
  46. 46. Paging
  47. 47. Paging
  48. 48. class MyPagedListAdapter(diffCallback: DiffCallback<User>) : PagedListAdapter<User, MyPagedListAdapter.ViewHolder>(diffCallback) { PagedListAdapter override fun onBindViewHolder(holder: MyPagedListAdapter.ViewHolder?, position: Int) { getItem(position)?.let { holder?.setData(it) } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyPagedListAdapter.ViewHolder { val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_user, parent, false) return ViewHolder(view) } }
  49. 49. class MyPagedListAdapter(diffCallback: DiffCallback<User>) : PagedListAdapter<User, MyPagedListAdapter.ViewHolder>(diffCallback) { PagedListAdapter override fun onBindViewHolder(holder: MyPagedListAdapter.ViewHolder?, position: Int) { getItem(position)?.let { holder?.setData(it) } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyPagedListAdapter.ViewHolder { val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_user, parent, false) return ViewHolder(view) } }
  50. 50. class MyPagedListAdapter(diffCallback: DiffCallback<User>) : PagedListAdapter<User, MyPagedListAdapter.ViewHolder>(diffCallback) { PagedListAdapter override fun onBindViewHolder(holder: MyPagedListAdapter.ViewHolder?, position: Int) { getItem(position)?.let { holder?.setData(it) } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyPagedListAdapter.ViewHolder { val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_user, parent, false) return ViewHolder(view) } }
  51. 51. DiffCallback private val diffCallback = object : DiffUtil.ItemCallback<User>() { override fun areItemsTheSame(oldItem: User, newItem: User): Boolean = oldItem.id == newItem.id override fun areContentsTheSame(oldItem: User, newItem: User): Boolean = oldItem == newItem } }
  52. 52. Query @Query("SELECT * FROM users ORDER WHERE age>:age ORDER by name DESC, id ASC") abstract fun usersOlderThan(age: Int): LivePagedListProvider<Int, User>
  53. 53. ViewModel class UserViewModel(val db:AppDB) : ViewModel() { val users: LiveData<PagedList<User>> fun getUsersOlderThan(age) { users = db.userDao().usersOlderThan(age) .create(0, PagedList.Config.Builder() .setPageSize(20) .setPrefetchDistance(20) .setEnablePlaceholders(false) .build()) } }
  54. 54. Activity viewModel.getUsersOlderThan(5).observe(this, pagedList -> { usersAdapter.setList(pagedList); });
  55. 55. Thank you Questions Kotlin and Android Arch Components @aditlal

×