0

I started playing around with Android JetPack (ViewModel, Architecture Components, LIfeCycle and so on). Untill now, I was working with Model View Presenter architecture, and actually I found it a quite easy to test and maintain architecture.

On the other hand, The big advantage I can see by using ViewModels instead, is their native coupling with Activities and Fragments lifecycle, which always was one of the biggest pains for Android developer, so I think this is a very big step forward.

Said that, I think there is a big disavantage though: with this new approach, it seems much more tricky to call Activity's or Fragment's methods, because, as stated in the official docs

A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.

In MVP approach, the Presenter had a contract with the view and could call all of its methods. I made some research on how to address this scenario with Architecture components, but it seem there is no easy and painless way to do that: at the end you always have to handle states in ViewModel and react to these changes in Activities and Fragments. Someone suggest to use SingleLiveEvent class, which makes it a little bit easier, but still much more painfull than before.

So my question is:

The docs say you cannot reference anything holding a reference to an Activity Context (to avoid memory leaks I guess), but what if I do that and then I clear all references in ViewModel's onCleared()?

Apperside
  • 3,542
  • 2
  • 38
  • 65

3 Answers3

1

You wouldn't avoid memory leaks, because for example if you rotate your device your activity will be destroyed, then recreated, but the VM would remain the same, and it's onCleared would not be called (hence your old activity still remains in memory, since your VM still references it).

Generally the MVVM conceptually says, that the ViewModels should not know about the View and this is the beauty of architecture: there is not a better pattern, just a more suitable one, and you should choose the one, that works better for you.

Róbert Nagy
  • 6,720
  • 26
  • 45
1

I can think of couple of ways to "notify a user" of the ViewModel:

  1. A LiveData object that changes and an Observer to this data
  2. Send a Broadcast to a BroadcastReceiver using the Application's Context, if you don't mind accessing it statically from the ViewModel

Edit: I know this is not exactly an answer to the question, but I think it removed the need for it

MikeL
  • 2,756
  • 2
  • 23
  • 41
0

but what if I do that and then I clear all references in ViewModel's onCleared()?

That is far too late. onCleared() is only called if the Activity is finished / the Fragment is removed, it is not called on configuration changes.


But you could potentially use some form of command queue to emit events only when a subscriber is available, for example DispatchWorkSubject in RxJava2-Extensions.

Just make sure you make your subscriptions in onStart and then dispose your disposable in onStop.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428