Viraj Tank
MBition GmbH
@viraj49
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4067534/ezgif.com-video-to-gif__2_.gif)
Viraj Tank
MBition
Mercedez-Benz Innovation Lab
@viraj49
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4067534/ezgif.com-video-to-gif__2_.gif)
God Activity Problem
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066326/Blank_Diagram_-_Page_1__3_.png)
Rise of Architectures
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066341/Blank_Diagram_-_Page_1__4_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066343/Blank_Diagram_-_Page_1__5_.png)
God P/VM Problem
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066341/Blank_Diagram_-_Page_1__4_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066343/Blank_Diagram_-_Page_1__5_.png)
Clean Architecture
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066391/Blank_Diagram_-_Page_1__8_.png)
Lifecycle Question
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4070453/Blank_Diagram_-_Page_1__21_.png)
Bind/Subscribe - onResume/onStart
UnBind/Dispose - onPause/onStop
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/3297972/ezgif.com-video-to-gif.gif)
View
Partially/
Fully
Blocked
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/3298084/device-2016-12-02-154600.png)
View
Partially/
Fully
Blocked
View Reloading Problem
RunTime Config Change
e.g. Orientation, Keyboard availability, Language, Docking etc
Android restarts running Activity
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/3301961/Blank_Diagram_-_Page_1__26_.png)
-
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4061310/device-2017-08-21-171839.png)
State Changing Action
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/3297972/ezgif.com-video-to-gif.gif)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4067530/ezgif.com-video-to-gif__1_.gif)
One Time Action
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4061227/device-2017-08-21-165504.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4067539/ezgif.com-video-to-gif__3_.gif)
- Lifecycle changes
- Configuration changes
-
View reloading
-
Data call may get interrupted
-
Context Leak
-
View state management
Problem Summary
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4192144/Blank_Diagram_-_Page_1__40_.png)
Android Architecture Components
-
Lifecycle
-
ViewModel
-
LiveData
-
Room*
-
Paging Library*
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4192009/final-architecture.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4189987/lifecycle-states.png)
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4189983/Blank_Diagram_-_Page_1__37_.png)
AAC- core concept
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066341/Blank_Diagram_-_Page_1__4_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4066343/Blank_Diagram_-_Page_1__5_.png)
Should I use ViewModel with MVP?
NO
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4069542/Blank_Diagram_-_Page_1__20_.png)
Can I use ViewModel with MVP?
YES
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4069542/Blank_Diagram_-_Page_1__20_.png)
- Lifecycle changes
- Configuration changes
-
Reloading the view -
Data call may get interrupted -
Context Leak -
View state management*
Problem Summary
SingleLiveEvent
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4190064/Blank_Diagram_-_Page_1__39_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/558875/images/4067785/1ulyfg.jpg)
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,760