Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use viewmodel singleton for activities?

MyApp need hold a User object in whole context,A,B,C activities'xml use this User object,when A edit User,I want B and C notifyChange,how to deal this problem with databinding,livedata and viewModel?

Formerly I make User.class extend BaseObservable,but POJO will be very troublesome and must not be a null,sometimes User maybe null such as not login. Now I Change to use LiveData, make Pojo simple and not extend BaseObservable,but when A edit,B and C not work,I think i need ABC use same viewModel instance in memory,but this will cause viewModel's onClear() trigger manytimes.

like image 740
candrwow Avatar asked Oct 29 '18 05:10

candrwow


3 Answers

Another way is to have one singleton repository to hold your user data and each viewModel can have that repository and share the same data between activities.

like image 81
Shayan Tabatabaee Avatar answered Oct 13 '22 09:10

Shayan Tabatabaee


Based on this part of the documentation: https://developer.android.com/topic/libraries/architecture/livedata#extend_livedata

The fact that LiveData objects are lifecycle-aware means that you can share them between multiple activities, fragments, and services. To keep the example simple, you can implement the LiveData class as a singleton as follows:

You can create a singleton for your view model like I did here:

    companion object{
        private lateinit var instance: ViewModelProfile
        
        @MainThread
        fun getInstance(userId: String): ViewModelProfile{
            instance = if(::instance.isInitialized) instance else ViewModelProfile(userId)
            return instance
        }
    }

Then I call it and get instance anywhere like this:

    val profileVModel = ViewModelProfile.getInstance(user.uid)
like image 25
fullmoon Avatar answered Oct 13 '22 09:10

fullmoon


If you want to share common ViewModel between ABC activities, then it is suggested to keep them as 3 fragments in a single Activity, create ViewModel of that Activity which can be shared among all three fragments A, B, and C.

Also what you are trying to achieve with activities is like this, suppose you have done some operation in activity A, if you want Activity B and C to get notified about them then they need to be running to get notified, which won't be happening, so instead you should use Intent or Bundle to pass needed information when the activity get started.

Updated

There are other ways as well to achieve similar kind of functionality like,

  • Event Bus
  • RxJava Subjects (refer this)
  • Android State by Evernote (refer this)

This will allow you to have application level access of state, which can be accessed by any Activity or Fragment

like image 45
Aseem Sharma Avatar answered Oct 13 '22 10:10

Aseem Sharma