IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Lifecycle详解 -> 正文阅读

[游戏开发]Lifecycle详解

先奉上lifecycle官方文档地址:
https://developer.android.com/topic/libraries/architecture/lifecycle

为什么要使用lifecycle?

现状:普通组件在使用过程中通常需要依赖于系统组件(Activity/Fragment/LifecycleService)的生命周期,导致系统组件的生命周期回调方法过于臃肿。例如通常在onCreate()中对组件进行初始化,在onPause()中停止组件,在onDestroy()中对组件进行资源回收等。

目标:解耦。监听应用组件的生命周期,在应用组件生命周期发生变化时,普通组件也能够及时收到通知,从而自行处理相应逻辑。

Google提供了Lifecycle作为解决方案,帮助开发者创建可感知生命周期的组件。组件便能够在其内部管理自己的生命周期,从而降低模块间的耦合度,并降低内存泄漏发生的可能性。

lifecycle原理

奉上原理结构图

在这里插入图片描述

  • Lifecycle
    Lifecycle是一个持有应用组件生命周期状态(如Activity/Fragment/LifecycleService)信息的抽象类。提供addObserver(添加观察者)和removeObserver(移除观察者)及getCurrentState(获取Lifecycle当前状态)的方法,都只能在主线程调用。类里面还枚举了Event和State,两者的映射关系在Lifecycle子类中有,见下文。
/**
     * Adds a LifecycleObserver that will be notified when the LifecycleOwner changes
     * state.
     * <p>
     * The given observer will be brought to the current state of the LifecycleOwner.
     * For example, if the LifecycleOwner is in {@link State#STARTED} state, the given observer
     * will receive {@link Event#ON_CREATE}, {@link Event#ON_START} events.
     *
     * @param observer The observer to notify.
     */
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    /**
     * Removes the given observer from the observers list.
     * <p>
     * If this method is called while a state change is being dispatched,
     * <ul>
     * <li>If the given observer has not yet received that event, it will not receive it.
     * <li>If the given observer has more than 1 method that observes the currently dispatched
     * event and at least one of them received the event, all of them will receive the event and
     * the removal will happen afterwards.
     * </ul>
     *
     * @param observer The observer to be removed.
     */
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    /**
     * Returns the current state of the Lifecycle.
     *
     * @return The current state of the Lifecycle.
     */
    @MainThread
    @NonNull
    public abstract State getCurrentState();
  • Event?:应用组件生命周期事件的枚举类。
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
    }
  • State?:Lifecycle当前状态的枚举类,这个状态和应用组件生命周期事件(Event类)具有对应关系见注释 =。=
  • LifecycleOwner?Lifecycle的持有者。主要作用是获取生命周期(Lifecycle对象,方法为Lifecycle getLifecycle();
  • LifecycleObserver?Lifecycle观察者
/**
 * Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on
 * {@link OnLifecycleEvent} annotated methods.
 * <p>
 * @see Lifecycle Lifecycle - for samples and usage patterns.
 */
@SuppressWarnings("WeakerAccess")
public interface LifecycleObserver {

}

LifecycleOwner通过getLifecycle()获取Lifecycle实例,通过实例类的addObserver(LifecycleObserver o)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

LifecycleRegistry Lifecycle具体类,其构造方法主要是持有LifecycleOwner的弱引用,一定程度防止内存泄露,并将生命周期状态设置为?INITIALIZED。

    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }

提供了添加观察者的方法

public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 将LifecycleObserver和State包装成ObserverWithState 见分析一
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // mObserverMap 存放的是LifecycleObserver和 ObserverWithState的集合                          
    //(FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new 
    //FastSafeIterableMap<>();)进去看下SafeIterableMap<K, V>就知道其本质是一个链表
、 
    // 如果是第一次存储这个ObserverWithState,就会返回null
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    // 判断是否存在这个ObserverWithState
    if (previous != null) {
        // 如果存在这个ObserverWithState就return
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    // 判断LifecycleOwner是不是null
    if (lifecycleOwner == null) {
        // 如果是null的话,应该立刻被销毁,快速回退
        return;
    }

    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可能被重新计算
        targetState = calculateTargetState(observer);
    }

    // 判断是不是在堆栈的顶层
    if (!isReentrance) {
        // 如果是在堆栈的顶层就执行同步 分析二
        sync();
    }
    mAddingObserverCounter--;
}
    //分析一
    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            //将LifecycleObserver 封装成LifecycleEventObserver 具体可以自己去看看源代码=。=
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        //获取最新状态,将最新状态赋值给当前状态。调用回调观察者的onStateChanged
        void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            //调用观察者的状态改变回调方法
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
    }


    //分析二
    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.");
        }
        //isSynced()是否同步了。见分析三
        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;
    }


    //分析三
    // mObserverMap 存放的是LifecycleObserver和 ObserverWithState的集合                          
    //(FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new 
    //FastSafeIterableMap<>();)进去看下SafeIterableMap<K, V>就知道其本质是一个链表

    //ObserverWithState 是持有生命周期状态的观察者,可以分发事件 上面分析过了
    private boolean isSynced() {
        //链表里面没有数据 返回true
        if (mObserverMap.size() == 0) {
            return true;
        }
        //否则将当前的State和最早的 State、最新的 State比较看是不是同一个。是同一个 则返回true
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }

    //分析四
    private void backwardPass(LifecycleOwner lifecycleOwner) {
        //倒序
        Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
                mObserverMap.descendingIterator();
        // 倒序遍历mObserverMap
        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));
                //状态变化则 调用ObserverWithState的dispatchEvent方法
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
    }
    

提供了移除观察者方法

public void removeObserver(@NonNull LifecycleObserver observer) {
        // we consciously decided not to send destruction events here in opposition to addObserver.
        // Our reasons for that:
        // 1. These events haven't yet happened at all. In contrast to events in addObservers, that
        // actually occurred but earlier.
        // 2. There are cases when removeObserver happens as a consequence of some kind of fatal
        // event. If removeObserver method sends destruction events, then a clean up routine becomes
        // more cumbersome. More specific example of that is: your LifecycleObserver listens for
        // a web connection, in the usual routine in OnStop method you report to a server that a
        // session has just ended and you close the connection. Now let's assume now that you
        // lost an internet and as a result you removed this observer. If you get destruction
        // events in removeObserver, you should have a special case in your onStop method that
        // checks if your web connection died and you shouldn't try to report anything to a server.
        mObserverMap.remove(observer);
    }

提供了处理应用组件生命周期事件的方法

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);//解析一
        moveToState(next);//解析二
    }

    //解析一 这里就是将应用组件的生命周期事件和枚举的状态做一个映射
    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);
    }

    //解析二 判断状态是否有变化 
    private void moveToState(State next) {
      //判断 当前 state 是不是等于我们上面获取的
        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;
    }


    
  • Fragment 在这个过程中就是生命周期持有者,实现了LifecycleOwner接口?(Activity、LifecycleService也是一样的)。在Fragment构造方法里面会初始化Lifecycle(initLifecycle)
    private void initLifecycle() {
            //获取LifecycleRegistry实例 然后为之添加观察者 ,在onStateChanged里面处理相关逻辑
            //LifecycleEventObserver继承LifecycleObserver,添加了onStateChanged回调方法
            this.mLifecycleRegistry = new LifecycleRegistry(this);
            this.mSavedStateRegistryController = SavedStateRegistryController.create(this);
            if (VERSION.SDK_INT >= 19) {
                this.mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
                    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
                        if (event == Event.ON_STOP && Fragment.this.mView != null) {
                            Fragment.this.mView.cancelPendingInputEvents();
                        }
    
                    }
                });
            }
    
        }

    在Fragment的每个生命周期事件中都会隐式调用mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.XXX);

流程总结

完整的流程就是Fragment构造方法的初始化Lifecycle(initLifecycle)方法中会

1、实例化LifecycleRegistry

2、LifecycleRegistry调用addObserver(@NonNull LifecycleObserver observer)添加LifecycleEventObserver事件观察者(实现onStateChanged回调方法接收生命周期事件)

3、addObserver方法中将观察者和状态封装成ObserverWithState ,并创建FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap链表,调用同步方法sync()。(会判重,不能重复添加)

4、在Fragment的每个生命周期事件中都会调用mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.XXX); handleLifecycleEvent里面也调用了sync()方法。

5、sync()中根据链表中的状态及当前状态判断状态是否发生变化。变化则 调用ObserverWithState的dispatchEvent方法进行事件分发。

6、dispatchEvent方法中会通知观察者状态发生变化。mLifecycleObserver.onStateChanged(owner, event);

ProcessLifecycIeOwner
具有生命周期的系统组件除Activity、Fragment、Service外,还有Application。有时候我们需要知道应用程序当前处在前台还是后台,或者应用程序从前台到后台/后台回到前台时,希望能得到通知。之前,Google并没有为该需求提供官方解决方案,直到LifeCycle的出现。LifeCycle提供了一个名为ProcessLifecycleOwner的类,来监听应用程序的生命周期。

使用

1、在app的build.gradle文件中添加相关依赖。

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

2、自定义一个observer,有两种方式。看下Lifecycle.java里面的一段注释 =。=

/* <p>
 * If you use <b>Java 8 Language</b>, then observe events with {@link DefaultLifecycleObserver}.
 * To include it you should add {@code "androidx.lifecycle:common-java8:<version>"} to your
 * build.gradle file.
 * <pre>
 * class TestObserver implements DefaultLifecycleObserver {
 *     {@literal @}Override
 *     public void onCreate(LifecycleOwner owner) {
 *         // your code
 *     }
 * }
 * </pre>
 * If you use <b>Java 7 Language</b>, Lifecycle events are observed using annotations.
 * Once Java 8 Language becomes mainstream on Android, annotations will be deprecated, so between
 * {@link DefaultLifecycleObserver} and annotations,
 * you must always prefer {@code DefaultLifecycleObserver}.
 * <pre>
 * class TestObserver implements LifecycleObserver {
 *   {@literal @}OnLifecycleEvent(ON_STOP)
 *   void onStopped() {}
 * }
 * </pre>
 */

第一种 实现 接口DefaultLifecycleObserver。在DefaultLifecycleObserver已经定义好了生命周期状态的方法,重写就行。

 class TestObserver implements DefaultLifecycleObserver {
     @Override
      public void onCreate(LifecycleOwner owner) {
          // your code
      }
 }

第二种实现 接口LifecycleObserver,然后使用注解@OnLifecycleEvent。

class TestObserver implements LifecycleObserver {
   @OnLifecycleEvent(ON_STOP)
   void onStopped() {}
}

3、创建LifecycleRegistry 实例,再进行调用。

//构造方法传入的是LifecycleOwner
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

//调用
mLifecycleRegistry.addObserver(new LifecycleEventObserver());

在AndroidX中ComponentActivity就加了挺多Lifecycle的,看下ImmLeaksCleaner。

首先InputMethodManager可能会造成内存泄露,而泄漏的原因是,mCurRootView, mServedView, mNextServedView持有context,导致activity销毁但是没有被回收,从而引发内存泄漏。

        if (19 <= SDK_INT && SDK_INT <= 23) {
            getLifecycle().addObserver(new ImmLeaksCleaner(this));
        }

ImmLeaksCleaner 具体源代码就不贴了,自己去看看=。=

它实现LifecycleEventObserver接口(LifecycleEventObserver extends LifecycleObserver),就是通过监听Activity的生命周期,在destroy时通过对存在内存泄漏的View设置为null来解决问题。

欢迎批评指正?=。=

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 16:02:57  更:2022-05-01 16:06:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 11:00:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码