一文读懂Jetpack LifeCycle的特性和实现

LifeCycle 生命周期

定义

Lifecycle是Jetpack架构组件中用来感知生命周期的组件,目标是使用Lifecycle可以帮助开发者写出与生命周期相关且更简洁、更易维护的代码(不将页面的生命周期透传给对应的组件)-- 监听者模式

使用方式

观察者:LifecycleObserver 和 LifecycleEventObserver

less 复制代码
//无接口,用注解的方式
public interface LifecycleObserver {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)


//使用接口的方式,无注解
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

宿主:LifeCycleOwner

Fragment,Activity等默认实现了LifeCycleOwner,直接调用getLifeCycle就可以

这里主要讲的是自定义LifeCycleOwner

csharp 复制代码
//暴露的LifecycleOwner接口
public interface LifecycleOwner {
@NonNull
    Lifecycle getLifecycle();
}

//具体的view的实现过程
public Lifecycle getLifecycle() {
    return mLifecycleRegistry; //返回的是注册器
}

//本质这是一个注册器
LifecycleRegistry mLifecycleRegistry;
//注册器和LifeCycleOwner绑定,LifeCycleOwner通过注册器和Observer绑定
mLifecycleRegistry = new LifecycleRegistry(this); //对应的是LifeCycleOwner,但是是弱引用的关系,避免了内存泄漏
//手动更新对应的生命周期(在Activity和Fragment是在源码中实现的)
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);

LifecycleRegistry允许手动设置生命周期通知观察者(使用场景是进行单测中手动更新状态)

绑定过程 :LifeCycleOwner绑定Observer

scss 复制代码
//在onCreate生命周期,需要在主线程
lifecycle.addObserver(fragmentLifecycleCallback)
//可以不需要removeObserver,因为在destroy的时候会自动清空

有默认实现LifecycleOwner的场景

  1. 需要首先在基础的地方有实现LifecycleOwner,下面的Activity默认实现了(FragmentActivity、AppCompatActivity以及Fragment都已经实现过了,可以直接使用)
scala 复制代码
public class ComponentActivity extends Activity implements LifecycleOwner
  1. 在基础类的地方增加注册
scss 复制代码
lifecycle.addObserver(advertisingManage)

应用场景

  1. 项目中一些通用的组件,不需要Activity每一个将生命周期都通知给它
  2. 在测试场景中可以通过LifeCycleRegistry mooc一些场景用于测试

优点

  1. 降低组件之间的耦合性,不需要逐层透传

缺点

  1. 灵活性强,不易维护:甚至可以自己既是一个Observer又是一个Owner
kotlin 复制代码
class FeedModel: LifecycleEventObserver, LifecycleOwner {
    constructor(feedRemoteSource: IFeedRemoteSource){
        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
lifecycleRegistry.addObserver(this)
    }
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }    
}

实现方式

如何实现注册 & 解注册

  1. 在addObserver的时候会立即获得一次生命周期回调的,因为源码中的循环和sync
  2. 在removeObserver的时候不发送额外的销毁DESTROYED事件(避免引入更多的监听者复杂度),因为removeObserver会自动移除
scss 复制代码
public void addObserver(@NonNull LifecycleObserver observer) {
    //必须是主线程注册
    enforceMainThreadIfNeeded("addObserver");  
    
    //根据当前的状态生成一个Observer并更新到对应的状态
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    
    //将注册的监听器放在FastSafeIterableMap中,这个是LinkedHashMap的简版,允许在遍历的时候更改数据不发生crash(是创建了迭代副本,在遍历的时候按照副本进行遍历)
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    
    //循环遍历上面的View全部状态(循环原因可以后面深究),但是明显
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

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

public void removeObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("removeObserver");
    //不发送额外的
    mObserverMap.remove(observer);
}

LifeCycleOwner是如何实现的

Android 10以下Activity本质是通过ReportFragment感知Activity生命周期拦截的(ReportFragment在ComponentActivity中注入的)

scss 复制代码
protected void onCreate(@Nullable Bundle savedInstanceState)
    ReportFragment.injectIfNeededIn(this);
}

public static void injectIfNeededIn(Activity activity) {
    //Android 10以上直接注册生命周期回调
    if (Build.VERSION.SDK_INT >= 29) {
        LifecycleCallbacks.registerIn(activity);
    }
    
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        //立即启动ReportFragment,以达到能够开始接收生命周期事件
        manager.executePendingTransactions();
    }
}

Fragment是通过LifeCycleRegistry实现的

javascript 复制代码
void performCreate(Bundle savedInstanceState) {
   //其中还通过LifeCycleOwner监听实现了:在OnStop生命周期的时候停止接受输入事件
   ....
   mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

为什么 Android 10 以上不再需要 ReportFragment?

  1. 能节省ReportFragment所占用的资源
  2. 能减少代码的复杂性
相关推荐
安妮的心动录1 小时前
人是习惯的结果
面试·程序员·求职
前端小巷子1 小时前
Promise 静态方法:轻松处理多个异步任务
前端·面试·promise
工呈士1 小时前
Context API 应用与局限性
前端·react.js·面试
移动开发者1号2 小时前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
移动开发者1号2 小时前
单线程模型中消息机制解析
android·kotlin
异常君2 小时前
@Bean 在@Configuration 中和普通类中的本质区别
java·spring·面试
sss191s4 小时前
校招 java 面试基础题目及解析
java·开发语言·面试
异常君4 小时前
MySQL 中 count(*)、count(1)、count(字段)性能对比:一次彻底搞清楚
java·mysql·面试
每次的天空4 小时前
Android第十五次面试总结(第三方组件和adb命令)
android
追随远方4 小时前
Android音频开发:Speex固定帧与变长帧编解码深度解析
android·音视频