Skip to content Skip to sidebar Skip to footer

Reacting To Activity Lifecycle In Viewmodel

I'm trying to create an app which will use MVVM architecture and there's one thing I quite don't understand. Official Android docs say that's not a good idea to reference activity

Solution 1:

If you need to have a ViewModel be lifecycle aware, then you can have it implement LifeCycleObserver and override life cycle events as necessary. Example,

publicclassMyModelextendsViewModelimplementsLifecycleObserver {

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP)protectedvoidonLifeCycleStop() {
      // do something
  }
}

In the activity or fragment then you can add the view model to the activity life cycle owner.

publicclassMyActivityextendsAppCompatActivity {

  protected MyModel mMyModel;

  @OverridepublicvoidonCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      mMyModel = ViewModelProviders
          .of(this)
          .get(MyModel.class);

      getLifecycle().addObserver(mMyModel);
  }
}

Solution 2:

I know ViewModel's shouldn't do business logic themselves

Yes, you're right. ViewModel should not contain business logic but it should contain UI related logic. So basically, API calls or Some location related stuffs should be avoided in ViewModel logic.

So what if you wanna make some scenario which can react to any activity lifecycle? I'll suggest you to use LifecycleObserver.

Why?, Because LifecycleObserver will provide you callbacks once it's LifecycleOwner will change it's state.

What is LifecycleOwner here? In our case it may be Activity/Fragment.


So, how you can achieve this?

Let's say you want to make location requests during resume & pause period of any activity.

So, for that you can create a class called LocationUpdates as LifecycleObserver like below:

classLocationUpdates : LifecycleObserver {constructor(){
    // some basic location related initialization here
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)funconnectListener() {
    // this method will respond to resume event of our Lifecycle owner (activity/fragment in our case)// So let's get location here and provide callback
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)fundisconnectListener() {
    // this method will respond to pause event of our Lifecycle owner (activity/fragment in our case)// So let's stop receiveing location updates here and remove callback
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)// Optional if you want to cleanup referencesfuncleanUp() {
    // this method will respond to destroy event of our Lifecycle owner (activity/fragment in our case)// Clean up code here
}
}

Now from your activity, you can directly make your LocationUpdates, and receive callback.

classMyActivity : AppCompatActivity() {

privatelateinitvar mLocationUpdates: LocationUpdates

overridefunonCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //Initialize your LifecycleObserver here & assign it to this activity's lifecycle
    lifecycle.addObserver(mLocationUpdates)
}
}

You can refer to how to handle Lifecycle & Codelabs example.


Edit:

If you want to have ViewModel for that job, consider this:

classMyViewModel : ViewModel {privatelateinitvar mLocationUpdates: LocationUpdates

constructor() : super() {
    // initialize LocationUpdates here
}

// Assign our LifecyclerObserver to LifecycleOwnerfunaddLocationUpdates(lifecycle: Lifecycle){
    lifecycle.addObserver(mLocationUpdates)
}

//Optional, we really don't need this.funremoveLocationUpdates(lifecycle: Lifecycle){
    lifecycle.removeObserver(mLocationUpdates)
}
}

If your LocationUpdates depends upon Context, consider using AndroidViewModel.

We can now observe our location updates @ any activity/fragment using LiveData, and assign our LifecycleObserver like below:

classMyActivity : AppCompatActivity() {

privateval viewModel: MyViewModel by lazy {
    return@lazy ViewModelProviders.of(this@MyActivity).get(MyViewModel::class.java)
}

overridefunonCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel.addLocationUpdates(lifecycle)
}
}

Please note:there's still lot to cover but making this answer as short as possible. So, if you're still confused about something related then please feel free to ask me in comment. I will edit my answer.

Post a Comment for "Reacting To Activity Lifecycle In Viewmodel"