I try to figure out how to in best way finish an Activity from ViewModel. I found the one way to do this using LiveData object and emitting "signal".
I have a doubt that this solution has a overhead. So is it right solution or I should use more accurate?
So go to example: let's suppose that in an app is an activity MainActivity and view model like below:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val model = ViewModelProviders.of(this).get(MainViewModel::class.java)
model.shouldCloseLiveData.observe(this, Observer { finish() })
}
}
and as a companion to the MainActivity is a MainViewModel like below:
class MainViewModel(app: Application) : AndroidViewModel(app) {
val shouldCloseLiveData = MutableLiveData<Void>()
fun someAction(){
shouldCloseLiveData.postValue(null)
}
}
The solution is, in the observable code, remove from the live data the observables linked to specific activity.
On Clicking the back button from the New Activity, the finish() method is called and the activity destroys and returns to the home screen.
In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.
Lifecycle Awareness: ViewModel objects are also lifecycle-aware. They are automatically cleared when the Lifecycle they are observing gets permanently destroyed. Data Sharing: Data can be easily shared between fragments in an activity using ViewModels .
I share your feelings that this solution does not look tidy for two reasons. First using a MutableLiveData
object to signal an event is a workaround. No data is changed. Second exposing LiveData to the outside of the view model violates the principle of encapsulation in general.
I am still surprised about this ugly concept of android. They should provide an option to observe the view model instead of it's internal LiveData
objects.
I experimented with WeakReference
s to implement the observer pattern. This was unstable. In an unpredictable manner the referent of the WeakReference
was lost (null
), in wich cases it was not possible to call finish()
. This was surprising as I don't think the activity is garbage collected while running.
So this is an partly answer by exclusion. The observer pattern implemented as WeakReference
seems to be no alternative to your suggestion.
A wonder if it is legitimate implement the observer pattern by hard references, if I remove the references during onStop()
, or onDestroy()
. I asked this question here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With