7

Jetpack框架探究01:Lifecycle组件的使用与源码分析

 3 years ago
source link: https://blog.csdn.net/AndrExpert/article/details/112346887
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Jetpack框架探究01:Lifecycle组件的使用与源码分析
Jetpack框架探究02:LiveData组件的使用与源码分析
Jetpack框架探究03:ViewModel组件的使用与源码分析
Jetpack框架探究04:Room组件的使用与源码分析
Jetpack框架探究05:WorkerManager组件的使用与源码分析

1. Lifecycle简介

 Lifecycle是Android Jetpack框架提供的能够感知组件(宿主)生命周期变化的组件,它能持有宿主(如Activity或Fragment)生命周期状态的信息,并且允许其他观察者注册监听宿主的生命周期状态变化,这就使得我们不用主动去获取宿主的状态,有利于降低代码耦合度并更容易维护。Lifecycle是JetPack组件库的核心基础,很多其他的Jetpack组件,比如LiveDataViewMoedel等,都是基于它实现的。

1.1 Lifecycle基本使用

 Lifecycle的使用非常简单,主要分为以下三步:

(1)添加依赖,直接导入androidx库即可;

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'

    // 如果需要支持 Java8 的组件,需要引入 lifecycle:common-java8
    // DefaultLifecycleObserver需要Java8
    implementation "android.arch.lifecycle:common-java8:1.1.1"
}

注:如果观察者使用继承DefaultLifecycleObserver方式,则需要Java8支持。

(2)实现一个观察者;

 创建一个观察者Observer主要有三种实现方式,即LifecycleObserverLifecycleEventObserverDefaultLifecycleObserver,其中,后两者均继承于LifecycleObserver,它是一个空的接口,如果直接继承这个接口,将通过注解的方式实现监听回调。但相比注解方式,官方更推荐使用DefaultLifecycleObserver,该接口也允许我们选择性的实现对应的回调方法。注意,它需要Java8支持。

class MyLifecycleObserver: DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Log.i("LifecycleObserver", "I'm observer, activity now in--->onStart")
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        Log.i("LifecycleObserver", "I'm observer, activity now in--->onStop")
    }
}

(3)注册观察者;

 为了实现对宿主生命周期状态的监听,我们需要将一个观察者对象注册到宿主中,这个过程主要是通过获取宿主的Lifecycle对象,并调用它的addObserver()方法实现的,该方法的具体实现在LifecycleRegister中,这个类是Lifecycle的唯一实现类。以监听Activity为例:

class StudyLifecycleActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        addLifecycleObserver()
    }

    private fun addLifecycleObserver() {
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

 至此,当Activity的生命周期变化时,与其对应的观察者方法将被回调。

1.2 Lifecycle实战案例

 为了加深对Lifecycle感知组件生命周期变化的理解,这里举一个在开发中经常遇到的例子,即判断APP是否显示在前台。本例需要结合Application的registerActivityLifecycleCallbacks()方法实现,该方法的作用是当Activity的生命周期发生变化时,其对应的方法就会被回调。基于此,我们创建一个自定义组件,使其继承于LifecycleOwner,并拥有Lifecycle.Event.ON_STARTLifecycle.Event.ON_STOP生命周期事件,分别表示APP的状态处于前台和后台。该组件具体源码如下:

/**
 * author: jiangdg
 * date: 2021/1/8 2:35 PM
 * description: 自定义宿主,拥有Start和Stop生命周期事件
 */
object AppStatusOwner:  LifecycleOwner {

    private val mLifecycleRegistry = LifecycleRegistry(this)

    override fun getLifecycle(): Lifecycle = mLifecycleRegistry

    fun init(application: Application) {
        application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
            private var activityFrontCount = 0

            override fun onActivityStarted(activity: Activity) {
                // 第一个activity置于前台时
                // 向外部发送Lifecycle.Event.ON_START事件,表示APP当前处于前台
                if (activityFrontCount == 0) {
                    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
                }

                activityFrontCount++
            }

            override fun onActivityStopped(activity: Activity) {
                activityFrontCount--

                // 当前没有Activity置于前台时
                // 向外部发送Lifecycle.Event.ON_STOP事件,表示APP当前处于后台
                if (activityFrontCount == 0) {
                    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
                }
            }

            override fun onActivityPaused(activity: Activity) {
            }

            override fun onActivityDestroyed(activity: Activity) {
            }

            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
            }

            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            }

            override fun onActivityResumed(activity: Activity) {
            }
        })
    }
}

 然后,我们通过继承DefaultLifecycleObserver创建一个观察者,并实现onStartonStop方法,当onStart()方法被回调时表明APP当前置于前台,当onStop()方法被回调时表明APP当前置于后台。代码如下:

/**
 * author: jiangdg
 * date: 2021/1/8 3:08 PM
 * description: APP前后台状态观察者
 */
class AppStatusObserver: DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)

        Log.i("AppStatusObserver", "APP置于前台")

        // 发送APP置于前台广播
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)

        Log.i("AppStatusObserver", "APP置于后台")

        // 发送APP置于前台广播
    }
}

 最后,在Application类中进行初始化操作。代码如下:

class JetpackApplication: Application() {

    override fun onCreate() {
        super.onCreate()
        
        // 启动监听所有Activity的状态变化
        AppStatusOwner.init(this)
        // 注册观察者到宿主
        AppStatusOwner.lifecycle.addObserver(AppStatusObserver())
    }
}

2. Lifecycle实现原理

2.1 Lifecycle框架模型

 Lifecycle框架类图如下:

在这里插入图片描述

 从Lifecycle框架模型可知,该框架感知一个组件的生命周期状态变化原理为:首先,让一个组件(如Activity或Fragment)继承LifecycleOwner接口,用以表明自己是一个拥有生命周期变化的组件(宿主),同时重写lifecycleOwner接口的getLifecycle()方法,该方法会返回一个Lifecycle对象;然后,通过继承LifecycleObserver接口实现一个观察者,并调用Lifecycle对象的addObserver()方法进行注册监听,当宿主生命周期发生变化时宿主内部就会通过Lifecycle的唯一实现类LifecycleRegister将生命周期事件分发给所有观察者;最后,观察者与生命周期事件对应的方法将会被自动回调。 类或接口具体说明如下:

  • LifecycleOwner

 LifecycleOwner是一个接口,它用于表明一个类是能够提供生命周期事件的宿主。Activity和Fragment均实现了LifecycleOwner,并重写了LifecycleOwner的getLifecycle()方法,该方法返回一个Lifecycle对象。当然,任何类均可以实现LifecycleOwner,表示该类是一个能够提供生命周期事件的宿主。LifecycleOwner源码如下:

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

 Lifecycle是一个抽象类,用于存储有关组件(或称宿主,比如Activity/Fragment)的生命周期状态的信息,并允许其他对象观察此状态。Lifecycle使用两种主要枚举跟踪其关联宿主的生命周期状态,即事件状态,其中,事件为宿主的生命周期事件,而状态为Lifecycle对象跟踪的宿主的当前状态,不同的事件可能对应相同的状态。Lifecycle源码如下:

public abstract class Lifecycle {

    // 注册生命周期事件观察者
    // 所有的观察者为LifecycleObserver或其子类
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    
    // 移除生命周期事件观察者
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
    // 获取Lifecycle当前的状态
    @MainThread
    @NonNull
    public abstract State getCurrentState();
    
    // 宿主生命周期
    // 比如ON_CREATE即为生命周期onCreate
    public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }

    // 宿主的状态类型
    // 比如CREATED状态对应于宿主生命周期为onCreate/onStop
    @SuppressWarnings("WeakerAccess")
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
        
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}
  • LifecycleRegister

 LifecycleRegister是Lifecycle的唯一实现类,主要用来负责注册Observer(观察者),以及分发宿主状态事件给这些观察者。LifecycleRegister维护着一个Map集合,该集合存储了已注册的观察者以及它们当前的状态,同时维护一个State对象表示当前宿主的状态,从LifecycleRegister的构造方法可以看出,宿主的初始状态为INITIALIZED。LifecycleRegister源码如下:

public class LifecycleRegistry extends Lifecycle {

    // Observer列表
    // ObserverWithState包装了要注册的Observer及其当前状态
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
        new FastSafeIterableMap<>();
    
    // 宿主当前状态
    private State mState
    
    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        // 初始状态INITIALIZED
        mState = INITIALIZED;
    }
    
    // 注册Observer
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        ...
    }
    
    // 移除Observer
    @Override
    public void removeObserver(@NonNull LifecycleObserver observer) {
        mObserverMap.remove(observer);
    }
    
    ...
}
  • LifecycleObserver

LifecycleObserver是一个接口,用于声明一个类为Lifecycle的观察者。LifecycleObserver是一个空的接口,通常我们使用注解或它的实现类,比如LifecycleEventObserverDefaultLifecycleObserver等,来监听宿主lifecycle的变化。源码如下:

// LifecycleObserver类
public interface LifecycleObserver {
}

// LifecycleEventObserver类
public interface LifecycleEventObserver extends LifecycleObserver {
    /**
     * 当宿主生命周期事件变化时,该方法被回调
     *
     * @param 宿主,即被观察的对象
     * @param event 生命周期事件
     */
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

// DefaultLifecycleObserver类
// 当使用Java 8时,推荐使用它
public interface DefaultLifecycleObserver extends FullLifecycleObserver {

   /**
     * 当宿主的生命周期事件为ON_CREATE时
     * 该方法被回调
     *
     * @param owner 宿主,即被观察的对象
     */
    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {
    }

    ...
}

2.2 Lifecycle状态模型

 Lifecycle状态模型描述了宿主生命周期宿主状态之间的关系,简单来说,就是指当宿主的生命周期变化时,它处于哪一种状态,总共有五种状态:INITIALIZEDCREATEDSTARTEDRESUMEDDESTROYED,LifecycleRegistry在分发事件时依赖这两种之间的关系。宿主生命周期与宿主状态模型图如下:

在这里插入图片描述

2.3 源码分析

2.3.1 Fragment实现Lifecycle原理

// androidx.fragment.app.Fragment
public class Fragment implements LifecycleOwner,.. 
{
    LifecycleRegistry mLifecycleRegistry;
    
    @Override
    @NonNull
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    
    private void initLifecycle() {
        mLifecycleRegistry = new LifecycleRegistry(this);
        mSavedStateRegistryController = SavedStateRegistryController.create(this);
    }
    
    void performCreate(Bundle savedInstanceState) {
        // 设置Fragment当前状态为CREATED
        mState = CREATED;
        onCreate(savedInstanceState);
        ...
        // 分发Fragment的生命周期onCreate
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }
    
    void performActivityCreated(Bundle savedInstanceState) {
        // 设置Fragment当前状为ACTIVITY_CREATED
        // 没有分发生命周期
        mState = ACTIVITY_CREATED;
        ...
        onActivityCreated(savedInstanceState);
    }
    
    void performStart() {
        mState = STARTED;
        onStart();
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
    
    void performResume() {
        mState = RESUMED;
        onResume();
        ...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
    
    void performPause() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        mState = STARTED;
        ...
        onPause();
    }
    
    void performStop() {
        mState = ACTIVITY_CREATED;
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        ...
        onStop();
    }
    
     void performDestroyView() {
        // 设置Fragment当前状为CREATED
        // 没有分发生命周期
        mState = CREATED;
        ...
        onDestroyView();
    }
    
    void performDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        mState = INITIALIZING;
        ...
        onDestroy();
    }
}

 从Fragment源码可知,它通过继承于LifecycleOwner接口,表明自己是一个拥有生命周期变化的组件,并实现该接口的getLifecycle()方法,该方法返回一个Lifecycle对象,实际上返回的是Lifecycle的唯一子类LifecycleRegistry。当Fragment的生命周期状态变化时,Fragment会更新自己的状态State,并通过LifecycleRegistry向外界(所有观察者)分发对应的生命周期事件。

2.3.2 Activity实现Lifecycler原理

// AppcompatActivity父类
public class ComponentActivity implements LifecycleOwner...{
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);
        // 将ReportFragment添加到Activity中
        ReportFragment.injectIfNeededIn(this);
        if (mContentLayoutId != 0) {
            setContentView(mContentLayoutId);
        }
    }
    
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    
    ...
}

// ReportFragment
public class ReportFragment extends Fragment {

    public static void injectIfNeededIn(Activity activity) {
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }
    
    ...
    
    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        // 调用LifecycleRegistry的handleLifecycleEvent方法
        // 向外分发生命周期变化事件
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
}

 从上述源码可知,Activity实现Lifecycle需要借助于ReportFragment往Activity上添加一个 fragment 用以报告生命周期的变化。目的是为了兼顾不是继承自 AppCompactActivity的场景,同时也支持我们自定义LifecycleOwner的场景。假如我们自定义一个继承于android.app.Activity的Activity需要实现Lifecycle,就需要借助于ReportFragment来实现。示例代码如下:

class StudyLifecycleActivity2: Activity(), LifecycleOwner {

    private val mLifecycleRegistry = LifecycleRegistry(this)
    
    // 返回一个LifecycleRegistry对象
    override fun getLifecycle(): Lifecycle = mLifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 添加ReportFragment到Activity
        ReportFragment.injectIfNeededIn(this)
        
        // 注册观察者
        addLifecycleObserver()
    }

    private fun addLifecycleObserver() {
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

2.3.3 事件分发过程

 Lifecycle事件分发时序图:

在这里插入图片描述

 从Fragment和Activity实现Lifecycle原理可知,当宿主的生命周期发生变化时,就会通过调用LifecycleRegistryhandleLifecycleEvent()方法向外分发生命周期变化事件,该方法源码如下:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    // (1)获取宿主当前生命周期事件对应的状态
    State next = getStateAfter(event);
    // (2)进入事件分发流程
    moveToState(next);
}

 事件分发具体过程如下:

 (1)调用getStateAfter()方法获取当前生命周期事件对应的状态;

static State getStateAfter(Event event) {
    switch (event) {
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        case ON_RESUME:
            return RESUMED;
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException("Unexpected event value " + event);
}

 (2)调用moveToState更新宿主的状态mState,然后调用sync方法通过比对宿主当前的状态和观察者之前保存的状态,完成观察者状态同步和事件分发。在sync方法中,首先会调用isSynced()方法判断是否需要同步观察者的状态;然后再判断当前事件的状态如果小于mObserverMap集合中最先添加的观察者状态,说明宿主的状态发生了回退,比如之前是RESUMED状态,执行了onPause()则回退到STARTED状态,此时就会调用backwardPass()方法把集合中的每一个观察者分发一个ON_PAUSE事件,并同步该观察者的状态。同理,如果当前事件宿主状态大于mObserverMap集合最近添加的观察者状态,说明宿主的状态发生了前进,此时就好调用forwardPass()分发事件,并同步该观察者状态。相关源码如下:

private void sync() {
    ...
    while (!isSynced()) {
        mNewEventOccurred = false;
        // 宿主状态回退
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        // 宿主状态前进
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

 在backwardPass()forwardPass()方法中,它们均会去遍历mObserverMap集合,获取与观察者关联的ObserverWithState对象,该对象存储了观察者及其状态。然后,判断这些Observer的状态State是否满足要求,如果满足,则调用dispatchEvent()方法同步观察者的状态,同时调用观察者的onStateChanged()方法完成宿主生命周期变化事件的分发。ObserverWithState源码如下:

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        // 同步观察者状态
        mState = min(mState, newState);
        // 分发生命周期变化事件
        // 注:这里表明了无论我们使用哪种方式实现观察者
        // Lifecycle源码中最终将统一转换为LifecycleEventObserver
        // 即通过它来完成最终的事件分发,以便统一分发形式
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

2.3.4 观察者注册过程

 Lifecycle注册观察者时序图:

在这里插入图片描述

 从上述时序图可知,Lifecycle的观察者注册是从调用LifecycleRegistryaddObserver()方法开始的,该方法首先会根据宿主当前的状态为新添加的观察者设定一个初始状态,只要不是在onDestory方法中注册,那么观察者的初始状态为INITIALIZED;然后将observer包装成ObserverWithState,并添加到mObserverMap集合中;最后就是一个while循环,即不断拿观察者的状态与宿主当前状态作比较以判断是否对齐,如果没有则向观察者分发对应的事件,同时更新观察者的状态,直到两者的状态一致。addObserver方法源码如下:

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    // 指定新添加观察者的初始状态
    // 只要不在onDestory方法中注册,初始状态为INITIALIZED
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 将observer包装成ObserverWithState,它存储了观察者及其状态
    // 使用ObserverWithState的目的就是方便在分发事件时作状态对比
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 将ObserverWithState添加到集合
    // 如果之前已经添加,则return
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        return;
    }
    
    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    // 同步观察者的状态,举个例子:
    //假设是在宿主的onresume犯法内注册的该观察者
    //第一次:分发on_Create事件,观察者状态INIT->CREATED 
    //第二次:分发on_Start事件,观察者状态CREATED->STARTED 
    //第三次:分发on_Resume事件,观察者状态STARTED->RESUMED
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        // 分发事件
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // 再一次计算观察的状态是否与宿主一致
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

Github源码:ExampleJetpack


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK