对ViewModel中的活动生命周期做出反应

时间:2018-09-29 07:05:58

标签: android mvvm android-lifecycle android-architecture-components

我正在尝试创建一个将使用MVVM架构的应用程序,有一件事我不太了解。

Android官方文档说在ViewModel的活动上下文中引用不是一个好主意(因为ViewModel可能会超出活动),所以当我想在恢复活动时执行一些操作时,我就开始怀疑用例。

我知道ViewModel本身不应该执行业务逻辑,但是即使我使用了某些服务类(例如GPSService,它必须启动并暂停每个时间的活动都必须在暂停时恢复),并且在此服务中,我会对onResume的活动做出反应(使用生命周期观察者)我仍将从ViewModel引用此活动,因为我正在引用服务,该服务持有对正在观察的活动的引用,这可能会导致活动泄漏(如果我错了,请纠正我)。

所以我的问题是,如何对MVVM体系结构中的活动或片段生命周期做出反应?

2 个答案:

答案 0 :(得分:5)

  

我知道ViewModel不应该自己进行业务逻辑

     

是的,您是对的。 ViewModel不应包含业务逻辑,但   它应该包含与UI相关的逻辑。所以基本上,API调用还是   应该使用ViewModel逻辑避免与位置有关的东西。

那么,如果您想提出一些可以对任何活动生命周期做出反应的方案,该怎么办?我建议您使用LifecycleObserver

为什么? ,因为LifecycleObserver将为您提供回调,一旦LifecycleOwner就会更改其状态。

这里的LifecycleOwner是什么?在我们的情况下,可能是活动/片段


那么,如何实现这一目标?

假设您要在任何活动的恢复和暂停期间进行定位请求。

因此,您可以创建一个名为LocationUpdates的类LifecycleObserver,如下所示:

class LocationUpdates : LifecycleObserver {

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

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
    // 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)
fun disconnectListener() {
    // 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 references
fun cleanUp() {
    // this method will respond to destroy event of our Lifecycle owner (activity/fragment in our case)
   // Clean up code here
}
}

现在,从您的活动中,您可以直接创建LocationUpdates,并接收回调。

class MyActivity : AppCompatActivity() {

private lateinit var mLocationUpdates: LocationUpdates

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

您可以参考 how to handle LifecycleCodelabs example


编辑:

如果您想为该工作准备ViewModel,请考虑以下事项:

class MyViewModel : ViewModel {
private lateinit var mLocationUpdates: LocationUpdates

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

// Assign our LifecyclerObserver to LifecycleOwner
fun addLocationUpdates(lifecycle: Lifecycle){
    lifecycle.addObserver(mLocationUpdates)
}

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

如果您的LocationUpdates依赖于Context,请考虑使用AndroidViewModel

我们现在可以使用LiveData观察任何活动/片段的位置更新,并像下面这样分配LifecycleObserver

class MyActivity : AppCompatActivity() {

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

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

请注意: 还有很多内容需要介绍,但请尽量简短。因此,如果您仍然对相关问题感到困惑,请随时在评论中问我。我将编辑我的答案。

答案 1 :(得分:3)

如果需要使ViewModel具有生命周期意识,则可以使它实现LifeCycleObserver并根据需要覆盖生命周期事件。例子

public class MyModel extends ViewModel implements
    LifecycleObserver {

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
  protected void onLifeCycleStop() {
      // do something
  }
}

在活动或片段中,您可以将视图模型添加到活动生命周期所有者中。

public class MyActivity extends AppCompatActivity {

  protected MyModel mMyModel;

  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

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

      getLifecycle().addObserver(mMyModel);
  }
}