使用Lifecycle简单管理生命周期

Lifecycle是Jetpack下的一员,旨在更好地管理生命周期,使用起来也极其简单,来看下吧。

一、感知Activity/Fragment的生命周期

以前的方式

还记得黑暗年代是怎么管理生命周期的么?嗯,复写onCreate()onDestroy()…在里面添加我们要做的逻辑,有多少写多少,只有你定义不完的需求,没有我写不完的代码。

第三方组件或者对象的调用,当然也在里面。比如我们要在Acticity销毁时调用:

@Override
protected void onDestroy() {
    super.onDestroy();
    
    //presenter代表其他类对象
    presenter.clear();
	
    //其他对象对Destroy周期的监听
    lifeListener.onDestroy();
    ....
}

熟悉吧,这样会有什么问题呢?稍微看一下吧:

  1. 复杂度增加,若需要,在每个对应的生命周期中都需要添加其他对象的调用;
  2. 对于被调用的对象而言,内部方法不能体现对应哪个生命周期,且不能固定调用方法的时机。比如presenter.clear()设计上只能是在OnDestroy()调用,但可能有不熟悉的同事,会增加在onResume()调用一下(可能空指针),这并没有约束。

以Lifecycle的方式

我们来看看以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打印log
跟你的设想是一样的吗?

二、传递Lifecycle判断当前生命周期

我们可以将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());

三、自定义LifecycleOwner

1.契约的来由

让我们再来看一看契约,也就是这一句

getLifecycle().addObserver(presenter);

我们已经知道getLifecycle()拿到的是一个Lifecycle对象,这个方法是哪来的呢,跟踪一下继承的AppCompatActivity,可以发现是其父类实现了LifecycleOwner接口
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了~

四、实践:LifecycleHandler

举个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把这种使用方式,优雅地摆在你面前,你会使用它吗?

发布了12 篇原创文章 · 获赞 36 · 访问量 4772

猜你喜欢

转载自blog.csdn.net/weixin_42229694/article/details/103856549