我正在尝试创建一个将使用MVVM架构的应用程序,有一件事我不太了解。
Android官方文档说在ViewModel的活动上下文中引用不是一个好主意(因为ViewModel可能会超出活动),所以当我想在恢复活动时执行一些操作时,我就开始怀疑用例。
我知道ViewModel本身不应该执行业务逻辑,但是即使我使用了某些服务类(例如GPSService,它必须启动并暂停每个时间的活动都必须在暂停时恢复),并且在此服务中,我会对onResume的活动做出反应(使用生命周期观察者)我仍将从ViewModel引用此活动,因为我正在引用服务,该服务持有对正在观察的活动的引用,这可能会导致活动泄漏(如果我错了,请纠正我)。
所以我的问题是,如何对MVVM体系结构中的活动或片段生命周期做出反应?
答案 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 Lifecycle和Codelabs 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);
}
}