Android Jetpack系列之LifeCycle的基本逻辑解析

挖个坑开始捋一遍Android的Jetpack架构相关重要概念原理,先上一张图:


谷歌Jetpack生态

谷歌之所以张罗这么一个开发标准出来是因为android开发的洪荒时期一直没有给开发者一个官方开发标准,于是android生态圈群魔乱舞,各种神仙打架,开发框架,功能组件很多都是开发者自行创建维护,而普通开发者在面对技术选型的时候也是非常纠结到底选哪个。
谷歌爸爸显然意识到了这个问题,于是推出了Jetpack这套官方开发套餐,从各个维度定义了官方推荐的开发模式。
不得不说这些技术还是很值得开发者去学习的,接下来我会挑一些典型代表,跟大家一起探究探究它的原理,来体会谷歌爸爸的这份良苦用心。
首先我们从架构出发,看看LifeCycle这套组件概念的高明之处,为什么从这个出发,因为后面的viewModel和LiveData都是基于生命周期管理去设计的,可以说处处有这个生命周期管理的身影。

LifeCycle的使命

lifeCycle出现之前,如果我们设计了一个要跟随Activity生命周期做出相应动作的组件,一般我们需要怎么做?你需要在你的Activity的onCreate(),onResume(),onPause(),onDestory()的各个生命周期方法回调里做相应的事情,比如当年接入百度地图sdk定位功能的代码:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        BaiDuLocationManager.getInstance().init()
    }

    override fun onResume() {
        super.onResume()
        StatusUtil.
        BaiDuLocationManager.getInstance().startLocation()
    }

    override fun onStop() {
        super.onStop()
        BaiDuLocationManager.getInstance().release()
    }

    override fun onDestroy() {
        super.onDestroy()
        BaiDuLocationManager.getInstance().release()
    }
}

有问题吗?好像是没有问题,以前我们就是这么过来的,但是这好看吗?优雅吗?解耦吗?会有成为屎山代码的可能吗?
比如你还有另外一个组件也是跟Activity的生命周期强相关,那么你的Activity里是不是要维护一堆的这样的组件,然后在生命周期方法里去管理他们,又假如你不止一个Activity里用到这些组件,在ABCD其他的Activity都要这些组件,那是不是管理起来特别繁琐,久而久之随着版本迭代就是一些定时炸弹,没准哪次迭代你改了组件的某个特性,需要把它的某个方法移到Activity别的生命周期方法里,你改了ActivityA但是忘记了改ActivityB,不要觉得这不可能,这些都是血泪教训!
还有一些更严重的问题,因为生命周期管理不当会导致一些无法预期的错误,举个例子:

class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
    }

    override fun onStart() {
        super.onStart()
        BaiduMapManager.checkDeviceStatus{isOk->
            //假设这里是个异步耗时操作,很久之后才回调,但是用户在这之前就按了返回键,这将导致
            // BaiDuLocationManager.getInstance().release()在init()之前就执行了,后续等到init()后,
            //release()释放方法永远得不到执行
            if(isOk){
                BaiDuLocationManager.getInstance().init()
            }
        }
    }

    override fun onStop() {
        super.onStop()
        BaiDuLocationManager.getInstance().release()
    }
}

如果引入了LifeCyle会是怎样的写法呢:

// 实现DefaultLifecycleObserver接口
class BaiDuLocationManager : DefaultLifecycleObserver {
    // onStart(owner: LifecycleOwner)会感知Activity的onStart方法后执行
    override fun onStart(owner: LifecycleOwner) {
        BaiduMapManager.checkDeviceStatus{isOk->
            if(isOk){
                // 此处可以判断异步回调后Activity当前状态是否是STARTED
                if(owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)){
                    init()
                }
                
            }
        }
    }
    // onStop(owner: LifecycleOwner)会感知Activity的onStop方法后执行
    override fun onStop(owner: LifecycleOwner) {
        release()
    }

    fun init(){

    }
    
    fun release(){

    }

}

然后在Activity里这样写:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 获取lifecycle,添加订阅者,即可完成生命周期的绑定,一看就知道是观察者模式那一套啦
        lifecycle.addObserver(BaiDuLocationManager.getInstance())
    }
}

这样一来你的Activity是不是非常简洁,其他的Activity想要添加这个组件也是这样简单的一句代码就能搞定。

OK,看了用法之后,我们来看看他的逻辑是怎么实现的,找出观察者和被观察者是怎么绑定的。
Lifecycle的基本逻辑

先来看看Activity是怎么支持获取lifecycle的,点击MainActivity的父类一直找,找到ComponentActivity,看看它实现了什么接口:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner

看到一个LifecycleOwner接口,Jetpack很喜欢用到Owener这个后缀去命名(看看后面三个接口都是什么什么Owner),大家要记住这个词尾,它的意思是拥有者,LifecycleOwner也就是生命周期拥有者的意思,很好理解,就是实现这个接口的就是实际的具有生命周期的组件,比如我们的Activity,点进去看看这个接口是怎样定义的:


/**
 * A class that has an Android lifecycle. These events can be used by custom components to
 * handle lifecycle changes without implementing any code inside the Activity or the Fragment.
 *一个拥有安卓生命周期的类,这些生命周期事件可以在不需要去实现Activity或Fragment里的任何生命周期方法
的情况下用来处理自定义组件的随着生命周期改变要做的一些事情
 * @see Lifecycle
 * @see ViewTreeLifecycleOwner
 */
@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

很简单的一个接口,只定义了一个方法 getLifecycle(),看英文注释也解释的很直白,接下来看看 getLifecycle()返回的类型Lifecycle ,直译就是生命周期:

public abstract class Lifecycle {
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    @NonNull
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    @MainThread
    @NonNull
    public abstract State getCurrentState();

    @SuppressWarnings("WeakerAccess")
    public enum Event {
  
        ON_CREATE,
     
        ON_START,
       
        ON_RESUME,
       
        ON_PAUSE,
     
        ON_STOP,
        
        ON_DESTROY,
       
        ON_ANY;

        @Nullable
        public static Event downFrom(@NonNull State state) {
            switch (state) {
                case CREATED:
                    return ON_DESTROY;
                case STARTED:
                    return ON_STOP;
                case RESUMED:
                    return ON_PAUSE;
                default:
                    return null;
            }
        }

        @Nullable
        public static Event downTo(@NonNull State state) {
            switch (state) {
                case DESTROYED:
                    return ON_DESTROY;
                case CREATED:
                    return ON_STOP;
                case STARTED:
                    return ON_PAUSE;
                default:
                    return null;
            }
        }

        @Nullable
        public static Event upFrom(@NonNull State state) {
            switch (state) {
                case INITIALIZED:
                    return ON_CREATE;
                case CREATED:
                    return ON_START;
                case STARTED:
                    return ON_RESUME;
                default:
                    return null;
            }
        }

        @Nullable
        public static Event upTo(@NonNull State state) {
            switch (state) {
                case CREATED:
                    return ON_CREATE;
                case STARTED:
                    return ON_START;
                case RESUMED:
                    return ON_RESUME;
                default:
                    return null;
            }
        }

     
        @NonNull
        public State getTargetState() {
            switch (this) {
                case ON_CREATE:
                case ON_STOP:
                    return State.CREATED;
                case ON_START:
                case ON_PAUSE:
                    return State.STARTED;
                case ON_RESUME:
                    return State.RESUMED;
                case ON_DESTROY:
                    return State.DESTROYED;
                case ON_ANY:
                    break;
            }
            throw new IllegalArgumentException(this + " has no target state");
        }
    }

 
    @SuppressWarnings("WeakerAccess")
    public enum State {
      
        DESTROYED,

        
        INITIALIZED,

     
        CREATED,

      
        STARTED,

       
        RESUMED;

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

又是接口,看他的结构,定义了3个抽象方法(注意三个方法都要求在主线程MainThread调用):

    // 添加LifecycleObserver 生命周期订阅者
   @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
   // 移除LifecycleObserver 生命周期订阅者
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    // 获取当前状态
    @MainThread
    @NonNull
    public abstract State getCurrentState();

里面还有一个Event 枚举类,此时暂时不去看那些枚举的具体含义,大概瞄一眼也知道是一些生命周期事件和状态的枚举。接下来返回ComponentActivity,看看它对LifecycleOwner的具体实现:

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

mLifecycleRegistry是Lifecycle的实现类LifecycleRegistry的对象,看看LifecycleRegistry:

public class LifecycleRegistry extends Lifecycle {
    ...略(先关注主要的几个实现方法,具体怎么实现的后面细扣,我们先把整个流程走一遍。)
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("addObserver"); //这里又强调了要在主线程执行 
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        // 把订阅者放到了一个mObserverMap里,典型的观察者模式。
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        ...略
    }
    @Override
    public void removeObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("removeObserver");//这里又强调了要在主线程执行
        mObserverMap.remove(observer); // 把订阅者从mObserverMap里移除
    }
    @Override
    public State getCurrentState() {
        return mState; // 返回当前的状态
    }
    // 这个就是当Activity有生命周期变更的时候会调用的方法,看名字就知道,处
    //理生命周期事件,里面的代码最终会调用到mObserverMap里存的订阅者,
    //执行他们相应的生命周期方法,达到通知生命周期变化通知的目的,
     public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent");
        moveToState(event.getTargetState());
    }
    ...略
}

至此整个观察者模式的链路就差事件通知的下发时机了,这时候我们肯定得往Activity里的生命周期方法里去找,但是在ComponentActivity找了一圈你会发现找不到,并没有哪个生命周期方法里直接调用了那个生命周期事件通知的方法,是的,我当初也是懵了一阵子,但是看源码的过程都必须经历时不时怀疑人生的时刻,但是请坚定该有的肯定有,无非是藏的比较深而已,最终我在ComponentActivity的onCreate()方法里看到了一个值得怀疑的Fragment----ReportFragment:

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);
        // 就是这个地方,额外用了一个Fragment来管理生命周期事件的分发
        ReportFragment.injectIfNeededIn(this);
        if (mContentLayoutId != 0) {
            setContentView(mContentLayoutId);
        }
    }

用Fragment来做额外的事情,在不少知名三方组件里都有类似的骚操作,比如glide也是用Fragment来管理图片加载中对Activity的生命周期感知,一些权限请求框架也是额外的起了一个Fragment来处理权限请求结果,这里不赘述,看看injectIfNeededIn(Activity activity)方法:

 public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            LifecycleCallbacks.registerIn(activity);
        }
        // 创建ReportFragment实例
        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();
        }
    }

AndroidSDK29以上才走LifecycleCallbacks.registerIn(activity)这套生命周期监听事件流程,29以下是直接在ReportFragment里的生命周期方法下发事件,这里暂不研究:

public class ReportFragment extends android.app.Fragment {
  static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

        static void registerIn(Activity activity) {
            activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
        }

        @Override
        public void onActivityPostCreated(@NonNull Activity activity,
                @Nullable Bundle savedInstanceState) {
            // 生命周期事件会随着Activity传到这里
            dispatch(activity, Lifecycle.Event.ON_CREATE);
        }

        @Override
        public void onActivityPostStarted(@NonNull Activity activity) {
            dispatch(activity, Lifecycle.Event.ON_START);
        }
        ···略
}
  static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        // 熟悉的LifecycleOwner,在这里终于传递过来了
        if (activity instanceof LifecycleOwner) {
            // 这里的lifecycle就是之前提到的LifecycleRegistry 
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
              if (lifecycle instanceof LifecycleRegistry) {
                // handleLifecycleEvent方法在这里调用了
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
              }
          }
    }
    
}

注意看activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
      ...略
    public void registerActivityLifecycleCallbacks(
            @NonNull Application.ActivityLifecycleCallbacks callback) {
          synchronized (mActivityLifecycleCallbacks) {
              mActivityLifecycleCallbacks.add(callback); // 又是套了一层观察者模式
          }
      }
      // 真正的万恶之源,终于找到了事件的源头
      protected void onCreate(@Nullable Bundle savedInstanceState) {
            
             dispatchActivityCreated(savedInstanceState);
      }
  
     private void dispatchActivityCreated(@Nullable Bundle savedInstanceState) {
          getApplication().dispatchActivityCreated(this, savedInstanceState);
          // 从集合里取出所有的观察者Application.ActivityLifecycleCallbacks
          Object[] callbacks = collectActivityLifecycleCallbacks();
          if (callbacks != null) {
              for (int i = 0; i < callbacks.length; i++) {
                 // 调用观察者相应的生命周期方法,完成事件通知下发 
                ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityCreated(this,
                        savedInstanceState);
              }
          }
      }
     protected void onStart() {
        
        dispatchActivityStarted();
    }
      private void dispatchActivityStarted() {
          getApplication().dispatchActivityStarted(this);
          Object[] callbacks = collectActivityLifecycleCallbacks();
          if (callbacks != null) {
              for (int i = 0; i < callbacks.length; i++) {
                  ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityStarted(this);
              }
          }
      }
}
 ...略

捋一下事件的传递过程,从Activity出发到被lifecycleObserver处理,无非就是观察者模式的典型,整个脉络还是很容易理清楚的,lifecycle的基本用法了解这些其实也就够用了,不过如果结合liveData和ViewModel,lifecycle的一些细节处理就需要更详细的去了解,后续会结合LiveData继续分析。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 197,737评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,103评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,710评论 0 326
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,909评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,794评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,557评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,939评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,572评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,852评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,871评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,692评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,490评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,939评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,114评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,409评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,971评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,176评论 2 339

推荐阅读更多精彩内容