Skip to content

Latest commit

 

History

History
315 lines (219 loc) · 11.5 KB

2.LifeCycle.md

File metadata and controls

315 lines (219 loc) · 11.5 KB
Error in user YAML: (<unknown>): could not find expected ':' while scanning a simple key at line 12 column 1
---

title: Lifecycle

date: 2019-05-16

categories: 
   - Jetpack

tags: 
   - Jetpack 

description: 

---

from: https://www.jianshu.com/p/b1208012b268

Lifecycle

Lifecycle 是一个类,它持有关于组件(如 Activity 或 Fragment)生命周期状态的信息,并且允许其他对象观察此状态。

使用

Presenter 继承 LifecycleObserver 接口

class MyPresenter : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun a1() {
        println("=====Lifecycle.Event.ON_CREATE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun a2() {
        println("=====Lifecycle.Event.ON_RESUME")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun a3() {
        println("=====Lifecycle.Event.ON_STOP")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun a4() {
        println("=====Lifecycle.Event.ON_DESTROY")
    }
}

在Activity/Fragment容器中添加Observer:

public class MainActivity extends AppCompatActivity {
    private IPresenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("tag", "onCreate" + this.getClass().toString());
        setContentView(R.layout.activity_main);
        mPresenter = new MyPresenter();
        getLifecycle().addObserver(mPresenter);//添加LifecycleObserver
    }

    @Override
    protected void onDestroy() {
        Log.d("tag", "onDestroy" + this.getClass().toString());
        super.onDestroy();
    }
}

如此,每当Activity发生了对应的生命周期改变,Presenter就会执行对应事件注解的方法.

除onCreate和onDestroy事件之外,Lifecycle一共提供了所有的生命周期事件,只要 通过注解进行声明,就能够使LifecycleObserver观察到对应的生命周期事件:

 public enum Event {
        /**
         * Constant for onCreate event of the {@link LifecycleOwner}.
         */
        ON_CREATE,
        /**
         * Constant for onStart event of the {@link LifecycleOwner}.
         */
        ON_START,
        /**
         * Constant for onResume event of the {@link LifecycleOwner}.
         */
        ON_RESUME,
        /**
         * Constant for onPause event of the {@link LifecycleOwner}.
         */
        ON_PAUSE,
        /**
         * Constant for onStop event of the {@link LifecycleOwner}.
         */
        ON_STOP,
        /**
         * Constant for onDestroy event of the {@link LifecycleOwner}.
         */
        ON_DESTROY,
        /**
         * An {@link Event Event} constant that can be used to match all events.
         */
        ON_ANY
    }

原理

主要是观察者设计模式

我们将 被观察的 称为主题 将观察者称为 观察者 Observer

  • LifecycleObserver 接口(Lifecycle观察者):实现该接口的类,通过注解的方式,可以通过被 Lifecycle 类的 addObserver(LifecycleObserver o) 方法注册,被注册后,LifecycleObserver便可以观察到 Lifecycle 的变化。

  • LifecycleOwner接口(Lifecycle的持有者):实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

  • Lifecycle(生命周期):和LifecycleOwner不同的是,LifecycleOwner本身持有Lifecycle对象,LifecycleOwner通过其Lifecycle getLifecycle()的接口获取内部Lifecycle对象。

  • State(当前生命周期所处状态):如图所示。

  • Event(当前生命周期改变对应的事件):如图所示,当Lifecycle发生改变,如进入onCreate,会自动发出ON_CREATE事件。

总结:

LifecycleObserver(观察者) 通过注册的方式, 观察主题(Lifecycle). 当 Lifecycle 变化的时候, LifecycleObserver就知道了.

那 lifecycle 什么时候变化呢?

让 LifecycleOwner 持有一个 Lifecycle(主题). 一般这个 LifecycleOwner 是一个 Fragment / Activity. 变化不变化, 是Fragment / Activity 说了算.

也就是说, 当 Activity / Fragment 的生命周期变化了, Activity / Fragment 会主动去调用 lifecycle 的方法, 让 lifecycle 去通知他的观察者. 这样, 就实现了感知 Activity / Fragment 生命周期变化的功能

LifecycleObserver 一般就是 想要知道 Fragment/Activity 的生命周期的对象, 比如我们的 Presenter .

Fragment (LifecycleOwner)

Fragment(Activity同理,我们 本文以Fragment为例,下同):实现了LifecycleOwner接口,这意味着Fragment对象持有生命周期对象(Lifecycle),并可以通过Lifecycle getLifecycle()方法获取内部的Lifecycle对象:

public class Fragment implements xxx, LifecycleOwner {
    
    //...省略其他

   LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

可以看到,实现的getLifecycle()方法,实际上返回的是 LifecycleRegistry 对象,LifecycleRegistry对象实际上继承了 Lifecycle,这个下文再讲。

持有Lifecycle有什么作用呢? 就是为了在Fragment对应的生命周期变化的时候,都会发送对应的生命周期事件给内部的 LifecycleRegistry 对象处理.

public class Fragment implements xxx, LifecycleOwner {
    //...
    void performCreate(Bundle savedInstanceState) {
        onCreate(savedInstanceState);  //1.先执行生命周期方法
        //...省略代码
        //2.生命周期事件分发
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    void performStart() {
        onStart();
        //...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    void performResume() {
         onResume();
        //...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    void performPause() {
        //3.注意,调用顺序变了
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        //...
        onPause();
    }

    void performStop() {
       mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        //...
        onStop();
    }

    void performDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        //...
        onDestroy();
    }
}

随着Fragment走到不同的生命周期,除了回调提供给我们的生命周期方法onCreate/onStart/..../onDestroy等,同时,还会调用Fragment内部的Lifecycle对象(就是mLifecycleRegistry)的 handleLifecycleEvent() 方法, 并将生命周期对应的事件作为参数传进去了。这样, Lifecycle就知道了发生什么事件

同时,你会发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。

当Fragment将生命周期对应的事件交给其内部的Lifecycle处理后, LifecycleObserver (就是我们上文自定义的Presenter),就能够接收到对应的生命周期事件,这是如何实现的呢?

Lifecycle 收到了事件通知, 就会通知他所有的观察者啦. 这样 Presenter 就知道啦

LifecycleRegistry:Lifecycle

首先确认一点,LifecycleRegistry 就是 Lifecycle 的子类:

public class LifecycleRegistry extends Lifecycle {
}
public abstract class Lifecycle {

        //注册LifecycleObserver (比如Presenter)
        public abstract void addObserver(@NonNull LifecycleObserver observer);
        //移除LifecycleObserver 
        public abstract void removeObserver(@NonNull LifecycleObserver observer);
        //获取当前状态
        public abstract State getCurrentState();

        public enum Event {
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_ANY
        }
        
       public enum State {
            DESTROYED,
            INITIALIZED,
            CREATED,
            STARTED,
            RESUMED;

            public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }
       }
}

作为Lifecycle的子类,LifecycleRegistry 能通过addObserver方法注册LifecycleObserver (就是Presenter),当LifecycleRegistry 本身的生命周期改变后(可以想象,内部一定有一个成员变量State记录当前的生命周期),LifecycleRegistry 就会逐个通知每一个注册的LifecycleObserver了 ,让 LifecycleObserver 去 执行对应的方法。

我们看一下 LifecycleRegistry 的handleLifecycleEvent()方法:

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }

看方法的名字我们就可以知道,handleLifecycleEvent方法会通过 getStateAfter 获取当前应处的状态并修改 Lifecycle本身的State 值,紧接着遍历所 LifecycleObserver 并同步且通知其状态发生变化,因此就能触发 LifecycleObserver 对应的生命周期事件。

因为在 Activity/Fragment 中, 我们将 Presenter 作为观察者, 注册到了 Activity/Fragment 的 LifecycleRegistry上了.因此, 这个时候, Presenter 就能收到通知了.

一些小Tips

  1. 首先,LifecycleRegistry 本身就是一个成熟的 Lifecycle 实现类,它被实例化在Activity和Fragment中使用,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,完全可以直接在自定义LifecycleOwner中new一个LifecycleRegistry成员并返回它(简而言之就是:直接拿来用即可)。

  2. 注解和DefaultLifecycleObserver的取舍 其次,Google的Lifecycle库中提供了一个 DefaultLifecycleObserver 类,方便我们直接实现LifecycleObserver接口,相比较于文中demo所使用的注解方式,Google官方更推荐我们使用 DefaultLifecycleObserver 类,并声明

Lifecycle 的最佳实践

  • 保持 UI 控制器(Activity 和 Fragment)尽可能的精简。它们不应该试图去获取它们所需的数据;相反,要用 ViewModel来获取,并且观察 LiveData将数据变化反映到视图中。

  • 尝试编写数据驱动(data-driven)的 UI,即 UI 控制器的责任是在数据改变时更新视图或者将用户的操作通知给 ViewModel。

  • 将数据逻辑放到 ViewModel 类中。ViewModel 应该作为 UI 控制器和应用程序其它部分的连接服务。注意:不是由 ViewModel 负责获取数据(例如:从网络获取)。相反,ViewModel 调用相应的组件获取数据,然后将数据获取结果提供给 UI 控制器。

  • 使用Data Binding来保持视图和 UI 控制器之间的接口干净。这样可以让视图更具声明性,并且尽可能减少在 Activity 和 Fragment 中编写更新代码。如果你喜欢在 Java 中执行该操作,请使用像Butter Knife 这样的库来避免使用样板代码并进行更好的抽象化。

  • 如果 UI 很复杂,可以考虑创建一个 Presenter 类来处理 UI 的修改。虽然通常这样做不是必要的,但可能会让 UI 更容易测试。

  • 不要在 ViewModel 中引用View或者 Activity的 context。因为如果ViewModel存活的比 Activity 时间长(在配置更改的情况下),Activity 将会被泄漏并且无法被正确的回收。