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

And*_*der 8 android mvvm android-lifecycle android-architecture-components

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

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

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

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

far*_*d_z 16

如果您需要让 ViewModel 具有生命周期感知能力,那么您可以让它实现 LifeCycleObserver 并根据需要覆盖生命周期事件。例子,

public class MyModel extends ViewModel implements
    LifecycleObserver {

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
  protected void onLifeCycleStop() {
      // do something
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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);
  }
}
Run Code Online (Sandbox Code Playgroud)


Jee*_*ede 8

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

你是对的。ViewModel不应包含业务逻辑,但应包含与UI相关的逻辑。因此,从ViewModel逻辑上讲,应避免使用API​​调用或某些与位置有关的东西。

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

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

这是LifecycleOwner什么 在我们的情况下,它可能是Activity / Fragment


那么,如何实现呢?

假设您要在任何活动的恢复和暂停期间提出位置请求。

所以,你可以创建一个名为类LocationUpdatesLifecycleObserver象下面这样:

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
}
}
Run Code Online (Sandbox Code Playgroud)

现在,从您的活动中,您可以直接进行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)
}
}
Run Code Online (Sandbox Code Playgroud)

您可以参考如何处理LifecycleCodelabs示例


编辑:

如果您想从事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)
}
}
Run Code Online (Sandbox Code Playgroud)

如果您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)
}
}
Run Code Online (Sandbox Code Playgroud)

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