Lifecycle是Jetpack下的一员,旨在更好地管理生命周期,使用起来也极其简单,来看下吧。
还记得黑暗年代是怎么管理生命周期的么?嗯,复写onCreate()
、onDestroy()
…在里面添加我们要做的逻辑,有多少写多少,只有你定义不完的需求,没有我写不完的代码。
第三方组件或者对象的调用,当然也在里面。比如我们要在Acticity销毁时调用:
@Override
protected void onDestroy() {
super.onDestroy();
//presenter代表其他类对象
presenter.clear();
//其他对象对Destroy周期的监听
lifeListener.onDestroy();
....
}
熟悉吧,这样会有什么问题呢?稍微看一下吧:
presenter.clear()
设计上只能是在OnDestroy()
调用,但可能有不熟悉的同事,会增加在onResume()
调用一下(可能空指针),这并没有约束。我们来看看以Lifecycle是怎么做的
1.在Activity中签订契约
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化对象
Presenter presenter = new Presenter();
//签订契约:以后生命周期的状态,我都会告诉你
getLifecycle().addObserver(presenter);
}
}
来看这句话getLifecycle().addObserver(new Presenter())
,简单翻译下就是 签下契约,我就给你力量(误)。我们拿到Activity的Lifecycle对象,并添加了一个它的观察者对象,这里是presenter,就可以感知activity的生命周期了。
2.对象类需实现的接口
契约签订是有代价的,代价只是…需要实现一个接口而已。
public class Presenter implements LifecycleObserver{
private static final String TAG = Presenter.class.getName();
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void initConfig() {
Log.d(TAG, "initConfig: ");
//...
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void testDestroy() {
Log.d(TAG, "testDestroy: ");
}
}
我们实现了LifecycleObserver接口,就可以用@OnLifecycleEvent
来标记生命周期要运行的对应方法了。
方法名是随意取的,运行时机取决于注解。这里注解了 onStart() 和 onDestroy() ,其他生命周期也有相应的Lifecycle.Event
注解事件,就不去列举了。来试着打印下:
跟你的设想是一样的吗?
我们可以将Lifecycle对象传入来判断生命周期状态,而不用担心内存泄漏。
public class Presenter implements LifecycleObserver{
private Lifecycle lifecycle;
//传入Lifecycle
public Presenter(Lifecycle lifecycle){
this.lifecycle = lifecycle;
}
private void doSomething(){
//判断当前的生命周期
if(lifecycle.getCurrentState().isAtLeast(Lifecycle.State.RESUMED)){
//...
}
}
}
-----
//在activity中onCreate()中的创建:
new Presenter(getLifecycle());
1.契约的来由
让我们再来看一看契约,也就是这一句
getLifecycle().addObserver(presenter);
我们已经知道getLifecycle()
拿到的是一个Lifecycle对象,这个方法是哪来的呢,跟踪一下继承的AppCompatActivity,可以发现是其父类实现了LifecycleOwner接口
很明显,契约的类间关系应该是这样的
lifecycleOwner.getLifecycle().addObserver(lifecycleObserver);
2.自定义LifecycleOwner
除了Activity、Fragment外,如Dialog并不能采用getLifecycle()
这种简单的方式去实现生命周期的管理。这时候就需要自行实现LifecycleOwner接口
public class MyDialog extends Dialog implements LifecycleOwner {
//LifecycleRegistry继承于Lifecycle
private LifecycleRegistry lifecycleRegistry;
public MyDialog(@NonNull Context context) {
super(context);
//创建lifecycleRegistry
lifecycleRegistry = new LifecycleRegistry(this);
}
//重写方法返回Lifecycle
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
protected void onStart() {
super.onStart();
//这里绑定resume,因为dialog本身没有onResume()
lifecycleRegistry.markState(Lifecycle.State.RESUMED);
}
@Override
public void dismiss() {
super.dismiss();
lifecycleRegistry.markState(Lifecycle.State.DESTROYED);
}
}
如上,我们只需要:
LifecycleOwner
接口getLifecycle()
方法返回创建好的lifecycleRegistry
。lifecycleRegistry.markState(Lifecycle.State.xxx)
这样就可以如同Activity/Fragment一样使用Lifecycle了~
举个Lifecycle使用的巧妙栗子,Handler的内存泄漏是常常被提及的话题。完成一个Handler来避免它吧!
public class LifecycleHandler extends Handler implements LifecycleObserver {
private Lifecycle lifecycle;
//构造方法中传入Lifecycle
public LifecycleHandler(final Lifecycle lifecycle) {
this.lifecycle = lifecycle;
addObserver();
}
...//其他构造方法同理
//添加观察者
private void addObserver() {
notNull(lifecycle);
lifecycle.addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void onDestroy() {
removeCallbacksAndMessages(null);
lifecycleOwner.getLifecycle().removeObserver(this);
}
}
这里用@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
在销毁时清空了Handler的消息队列。
好了!我想我们应该这样评价它,Lifecycle是一种最佳实践,也就是 不是非你不可,只是有你更好。Google把这种使用方式,优雅地摆在你面前,你会使用它吗?