android LifeCycle-简单使用和详细原理解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: android LifeCycle-简单使用和详细原理解析

Lifecycle是用来做什么的


Lifecycle 用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。


更通俗的说,你可一通过注册回调的方式,拿到我们activity的所有生命周期方法回调

下图展示了观察生命周期的机制的所有类型

image.png


使用方法


总的来说LifeCycle的使用非常简单,基本没什么好写的,使用方法的章节仅限于绝对新手参考。

说是徒劳的,先上一波简单使用的代码吧


代码展示

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(MainObserver())
    }
}
class MainObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create(){
        logEE("create")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start(){
        logEE("start")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun resume(){
        logEE("resume")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun pause(){
        logEE("pause")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop(){
        logEE("stop")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destroy(){
        logEE("destroy")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun any(){
        logEE("any")
    }
}
复制代码

运行后我们执行如下流程: 启动app-点击回退键退出app,查看生命周期日志打印:


效果展示

image.png

我们发现所有的生命周期回调都被调用了,并且每个生命周期调用后都会马上同步调用ON_ANY注解的方法


使用LifeCycle处理异常状态


异常状态说明

我所说的异常状态需要举一个例子:

比如我们现在启动了一个耗时任务去请求网络,然后当网络请求完成后要回来更新ui,我们的异常状态就是指网络请求完成前我们主动关闭了activity。正常情况下这个时候就会造成内存泄露,再次更新ui明显是一个异常状态。本例中我们就需要使用LifeCycle解决此类异常状态。


用到的方法

lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
复制代码


测试案例说明和实现

案例说明:

在注册观察者的onCreate方法监听中使用Thread.sleep模拟一个4s耗时任务,然后在Activity中监听任务的回调并打印日志。我们需要模拟两种操作:

  1. 不关闭页面等待耗时任务完成,耗时任务结束后查看日志
  2. 在耗时任务结束前关闭页面,耗时任务结束后查看日志


代码展示

注册监听的观察者代码:

lifecycle.addObserver(MainObserver {
            runOnUiThread {
                if(lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)){
                    tv.text="耗时任务完成"
                    logEE("耗时任务完成,并成功更新ui")
                }else{
                    logEE("生命周期状态不匹配,不能更新ui")
                }
            }
        })
复制代码


处理耗时任务的代码:

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create(){
        thread {
            Thread.sleep(4000)
            fun0()
        }
    }
复制代码


两种情况对应的日志

不关闭页面等待耗时任务完成,耗时任务结束后查看日志:

image.png

在耗时任务结束前关闭页面,耗时任务结束后查看日志

image.png


结论

是使用LifeCycle的lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)方法可以判断Activity当前的状态,从而灵活的处理异常状态


LifeCycle实现原理


基本原理

先大概的说一下基本的原理:

我们的AppComponentActivity和FragmentActivity都是继承了ComponentActivity。

ComponentActivity实现了LifecycleOwner接口。

在ComponentActivity的onCreate生命周期回调中会添加一个Fragment

所以我们就是借助Fragment来实现生命周期的观察的

这种实现原理机制并不少见,例如Glide、RxPremission都是用的这种方式实现

我总体上把代码讲解分为了下面四个部分

  1. ComponentActivity中注册Fragment
  2. addObserver添加监听者方法讲解
  3. Fragment中生命周期方法联动回调
  4. 如何回调注解方法

看完后把这四部分相关结合起来理解,就能彻底搞懂LifeCycle源码了


对四部分代码进行讲解

ComponentActivity中注册Fragment

  1. 注入Fragment

AppComponentActivity

ReportFragment.injectIfNeededIn(this);
复制代码


android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
复制代码

这里主要负责把Fragment添加到activity中


addObserver方法讲解

  1. 方法调用

这个方法会调用到LifecycleRegistry的addObserver

@Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }
        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }
复制代码


首先会创建ObserverWithState对象,用来记录生命周期状态,

State targetState = calculateTargetState(observer);

方法会计算出此时的生命周期状态,

后面是一个while循环,while循环会分发生命周期状态

比如你在onResume中进行注册其实也是可以收到onCreate和onStart的注册回调的,这种注册方式实际上就是粘性注册,安卓系统中电量信息的广播接受者就是一种很好的粘性广播注册案例,与这个粘性注册原理相同

后面代码中的方法调用如下

if (!isReentrance) {
      // we do sync only on the top level.
      sync();
  }
复制代码

isReentrance为false的条件是,当前没有在moveToState方法中分发消息,或者注册者的数量不等于0。如果满足这个条件就会调用sync()方法分发消息


Fragment中生命周期方法联动回调

  1. ReportFragment中生命周期方法回调

例如:

dispatch(Lifecycle.Event.ON_DESTROY);
复制代码


private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
       ***
        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
复制代码

代码中会把Fragment中的所有生命周期回调都调用dispatch方法进行分发,dispatch方法中会调用lifecycle的handleLifecycleEvent方法继续分发


  1. 跳到LifecycleRegistry类中,找到handleLifecycleEvent方法
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }
复制代码

getStateAfter方法主要用来确认事件触发时下一个生命周期的状态,有下面三种:

CREATED、STARTED、DESTROYED


moveToState方法更改生命周期状态并分发,代码如下:

private void moveToState(State next) {
        if (mState == next) {
            return;
        }
        mState = next;
        if (mHandlingEvent || mAddingObserverCounter != 0) {
            mNewEventOccurred = true;
            // we will figure out what to do on upper level.
            return;
        }
        mHandlingEvent = true;
        sync();
        mHandlingEvent = false;
    }
复制代码

moveToState中的sync()方法用来分发生命周期事件到Observer,


  1. sync() 方法
private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                    + "garbage collected. It is too late to change lifecycle state.");
        }
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            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;
    }
复制代码

下面代码是State的几种状态

public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
}
复制代码


sync方法的while循环中有如下代码:

if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
复制代码

上面这行代码会比较当前生命周期状态和最早被加入到SafeIterableMap中的状态,如果小于零(比如一般第一个被加入的是INITIALIZED状态,当前状态比ONCREATE还小只能是DESTROYED状态了),说明当前生命周期需要被backwardPass处理


Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
复制代码

上面代码中newest是最新被添加到mObserverMap中的状态,如果当前生命周期状态大于newest状态,说明状态在前进(比如onCreate到onStart)


  1. 继续看backwardPass和forwardPass方法
private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();//获取正序的迭代器
        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
                popParentState();
            }
        }
    }
    private void backwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
                mObserverMap.descendingIterator();//获取逆向迭代器
        while (descendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);
                pushParentState(getStateAfter(event));
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
    }
复制代码


forwardPass和backwardPass都有三句重要代码:

pushParentState(getStateAfter(event));
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
复制代码

pushParentState(getStateAfter(event));

向列表中存入状态

observer.dispatchEvent(lifecycleOwner, event);

向Observer分发状态

popParentState();

弹出上一步代码中存入的状态


  1. 查看dispathchEvent方法
void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
复制代码

这里的mLifecycleObserver.onStateChanged(owner, event);最终会回调到我们声明的注解方法,mLifecycleObserver的实例是ReflectiveGenericLifecycleObserver,ReflectiveGenericLifecycleObserver最终通过反射的方式回调注解方法,这一部分下一节会详细讲


如何回调注解方法

说到注解方法回调就不得不提addObserver方法了,在LifecycleRegistry类的addObserver方法中,我们创建了一个ObserverWithState对象,并放到Map中

实际上在ObserverWithState方法的构造中就会对注解方法进行包装处理,从而最终用反射回调方法,下面开始代码解析:


ObserverWithState方法的构造如下

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


mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);

这一行代码最终获得的mLifecycleObserver实例的真实类型是ReflectiveGenericLifecycleObserver

ObserverWithState的dispatchEvent方法如下

void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
复制代码


在dispatchEvent方法中,会调用

mLifecycleObserver.onStateChanged(owner, event);

代码进行消息分发,实际上就是调用ReflectiveGenericLifecycleObserver.onStateChanged方法。

那么我就看看ReflectiveGenericLifecycleObserver类中的代码吧

class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final CallbackInfo mInfo;
    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }
    @Override
    public void onStateChanged(LifecycleOwner source, Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}
复制代码


ReflectiveGenericLifecycleObserver类构造参数中的wrapped对象就是我们addObserver中注册的自定义Observer对象。

在构造中通过一些了反射操作拿到Observer对象中的信息封装成了CallbackInfo对象。

然后当我们在ObserverWithState中调用ReflectiveGenericLifecycleObserver的onStateChanged方法的时候,就会调用如下代码:

mInfo.invokeCallbacks(source, event, mWrapped);

invokeCallbacks方法的方法体已经后续调用的代码如下:

@SuppressWarnings("ConstantConditions")
        void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
            invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
            invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
                    target);
        }
        private static void invokeMethodsForEvent(List<MethodReference> handlers,
                LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
            if (handlers != null) {
                for (int i = handlers.size() - 1; i >= 0; i--) {
                    handlers.get(i).invokeCallback(source, event, mWrapped);
                }
            }
        }
复制代码


上面这一大坨代码最终会调用到MethodReference的如下代码

void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
            //noinspection TryWithIdenticalCatches
            try {
                switch (mCallType) {
                    case CALL_TYPE_NO_ARG:
                        mMethod.invoke(target);
                        break;
                    case CALL_TYPE_PROVIDER:
                        mMethod.invoke(target, source);
                        break;
                    case CALL_TYPE_PROVIDER_WITH_EVENT:
                        mMethod.invoke(target, source, event);
                        break;
                }
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Failed to call observer method", e.getCause());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
复制代码

这里就是终点了,最终通过

mMethod.invoke(target);

调用java反射方法的方式执行我们自定义的注解方法



相关文章
|
1月前
|
存储 缓存 算法
HashMap深度解析:从原理到实战
HashMap,作为Java集合框架中的一个核心组件,以其高效的键值对存储和检索机制,在软件开发中扮演着举足轻重的角色。作为一名资深的AI工程师,深入理解HashMap的原理、历史、业务场景以及实战应用,对于提升数据处理和算法实现的效率至关重要。本文将通过手绘结构图、流程图,结合Java代码示例,全方位解析HashMap,帮助读者从理论到实践全面掌握这一关键技术。
90 13
|
2月前
|
运维 持续交付 云计算
深入解析云计算中的微服务架构:原理、优势与实践
深入解析云计算中的微服务架构:原理、优势与实践
98 1
|
2月前
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
9天前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
20天前
|
存储 物联网 大数据
探索阿里云 Flink 物化表:原理、优势与应用场景全解析
阿里云Flink的物化表是流批一体化平台中的关键特性,支持低延迟实时更新、灵活查询性能、无缝流批处理和高容错性。它广泛应用于电商、物联网和金融等领域,助力企业高效处理实时数据,提升业务决策能力。实践案例表明,物化表显著提高了交易欺诈损失率的控制和信贷审批效率,推动企业在数字化转型中取得竞争优势。
80 14
|
28天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
103 1
|
1月前
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
2月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
101 17
|
1月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
2月前
|
存储 供应链 算法
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
80 0

热门文章

最新文章

推荐镜像

更多