Viraj Tank
MBition GmbH
@viraj49
Viraj Tank
MBition
Mercedez-Benz Innovation Lab
@viraj49
God Activity Problem
Rise of Architectures
God P/VM Problem
Clean Architecture
Lifecycle Question
Bind/Subscribe - onResume/onStart
UnBind/Dispose - onPause/onStop
View
Partially/
Fully
Blocked
View
Partially/
Fully
Blocked
View Reloading Problem
RunTime Config Change
e.g. Orientation, Keyboard availability, Language, Docking etc
Android restarts running Activity
-
View reloading
-
Data call may get interrupted
-
Context Leak
-
View state management
View State Management
-
View data
-
State changing action
-
One time action
View Data
State Changing Action
One Time Action
- Lifecycle changes
- Configuration changes
-
View reloading
-
Data call may get interrupted
-
Context Leak
-
View state management
Problem Summary
Android Architecture Components
-
Lifecycle
-
ViewModel
-
LiveData
-
Room*
-
Paging Library*
AAC - Lifecycle
AAC - ViewModel
-
Retained Fragment Storage
-
Lifecycle Aware
-
onDestroy() clean up
-
onCleared() clean up
AAC - LiveData
-
~ Hot Observables
-
Lifecycle Aware
-
STARTED or RESUMED
-
onDestroy() clean up
AAC- core concept
Should I use ViewModel with MVP?
NO
Can I use ViewModel with MVP?
YES
- Lifecycle changes
- Configuration changes
-
Reloading the view -
Data call may get interrupted -
Context Leak -
View state management*
Problem Summary
SingleLiveEvent
Activity
class MyActiviy : LifecycleActivity() {
class MyActiviy : LifecycleActivity() {
private val myViewModelFactory = MyViewModelFactory()
private lateinit var myViewModel: MyViewModel
class MyActiviy : LifecycleActivity() {
private val myViewModelFactory = MyViewModelFactory()
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myViewModel = ViewModelProviders.of(this, myViewModelFactory)
.get(MyViewModel::class.java)
class MyActiviy : LifecycleActivity() {
private val myViewModelFactory = MyViewModelFactory()
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myViewModel = ViewModelProviders.of(this, myViewModelFactory)
.get(MyViewModel::class.java)
myViewModel.myLiveData.observe(this, Observer {
/* Update View */
})
}
}
Fragment
class MyFragment : LifecycleFragment() {
private val myViewModelFactory = MyViewModelFactory()
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myViewModel = ViewModelProviders.of(this, myViewModelFactory)
.get(MyViewModel::class.java)
myViewModel.myLiveData.observe(this, Observer {
/* Update View */
})
}
}
ViewModelFactory
class MyViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
return MyViewModel() as T
}
throw IllegalArgumentException("Unknown MyViewModel class")
}
}
ViewModel
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
private var myViewState = MyViewState()
val myLiveData = MutableLiveData<MyViewState>()
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
private var myViewState = MyViewState()
val myLiveData = MutableLiveData<MyViewState>()
init {
getData()
}
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
private var myViewState = MyViewState()
val myLiveData = MutableLiveData<MyViewState>()
init {
getData()
}
fun getData() {
dataSubscriptions.add(myDataSource.getData())
.subscribeOn(Schedulers.computation())
.observeOn(Schedulers.computation())
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
private var myViewState = MyViewState()
val myLiveData = MutableLiveData<MyViewState>()
init {
getData()
}
fun getData() {
dataSubscriptions.add(myDataSource.getData())
.subscribeOn(Schedulers.computation())
.observeOn(Schedulers.computation())
.subscribe({ data ->
myViewState = myViewState.copy(myData = data)
myLiveData.postValue(myViewState)
})
}
class MyViewModel : ViewModel() {
private val dataSubscription = CompositeDisposable()
private var myViewState = MyViewState()
val myLiveData = MutableLiveData<MyViewState>()
init {
getData()
}
fun getData() {
dataSubscriptions.add(myDataSource.getData())
.subscribeOn(Schedulers.computation())
.observeOn(Schedulers.computation())
.subscribe({ data ->
myViewState = myViewState.copy(myData = data)
myLiveData.postValue(myViewState)
})
}
override fun onCleared() {
dataSubscription.dispose()
super.onCleared()
}
}
Summary
- Lifecycle changes
- Configuration changes
-
Reloading the view
-
Data call may get interrupted
-
Context Leak
-
Recreating view state
- MVVM
- Clean Architecture
- Android Arch Components
Thanks
Offline first using Android Architecture Components
By Viraj Tank
Offline first using Android Architecture Components
How to design an offline first experience using Android Architecture Components
- 1,792