<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          @OnLifecycleEvent 被廢棄,替代方案是?

          共 3229字,需瀏覽 7分鐘

           ·

          2021-11-08 15:41

          ?BATcoder技術(shù)群,讓一部分人先進大廠

          大家,我是劉望舒,騰訊TVP,著有三本業(yè)內(nèi)知名暢銷書,連續(xù)四年蟬聯(lián)電子工業(yè)出版社年度優(yōu)秀作者,百度百科收錄的資深技術(shù)專家。

          前華為架構(gòu)師,現(xiàn)獨角獸技術(shù)負責人


          想要加入?BATcoder技術(shù)群,公號回復BAT?即可。


          近期 androidx.lifecycle 發(fā)布了 2.4.0 版本,此次更新中 @OnLifecycleEvent 注解被廢棄,官方建議使用 LifecycleEventObserver 或者 DefaultLifecycleObserver 替代

          現(xiàn)代的 Android 應(yīng)用中都少不了 Lifecycle 的身影,正是各種 lifecycle-aware 組件的存在保證了程序的健壯性。

          Lifecycle 本質(zhì)是一個觀察者模式的最佳實踐,通過實現(xiàn) LifecycleObserver 接口,開發(fā)者可以自自定 lifecycle-aware 組件,感知 Activity 或 Fragment 等 LifecycleOwner 的生命周期回調(diào)。

          趁新版本發(fā)布之際,我們再回顧一下 Lifecycle 注解的使用以及廢棄后的替代方案

          Lifecycle Events & States

          Lifecyce 使用兩組枚舉分別定義了 EventState

          • Events

            • ON_CREATE
            • ON_START
            • ON_RESUME
            • ON_PAUSE
            • ON_STOP
            • ON_DESTROY
            • ON_ANY
          • States

            • INITIALIZED
            • CREATED
            • STARTED
            • RESUMED
            • DESTROYED

          Events 對應(yīng)了 Activity 等原生系統(tǒng)組件的生命后期回調(diào), 每當 Event 發(fā)生時意味著這些 LifecycleOwner 進入到一個新的 State

          作為 觀察者的 LifecycleObserver 可以感知到 被觀察者的 LifecycleOwner 其生命周期 State 變化時的 Event。定義 LifecycleObserver 有三種方式:

          1. 實現(xiàn) LifecycleEventObserver 接口
          2. 使用 @OnLifecycleEvent 注解

          實現(xiàn) LifecycleEventObserver

          public?interface?LifecycleEventObserver?extends?LifecycleObserver?{
          ????void?onStateChanged(@NonNull?LifecycleOwner?source,?@NonNull?Lifecycle.Event?event);
          }

          LifecycleEventObserver 是一個單方法接口,在 Kotlin 中可轉(zhuǎn)為寫法更簡潔的 Lambda 進行聲明

          val?myEventObserver?=?LifecycleEventObserver?{?source,?event?->
          ????when(event)?{
          ????????Lifecycle.Event.ON_CREATE?->?TODO()
          ????????Lifecycle.Event.ON_START?->?TODO()
          ????????else?->?TODO()
          ????}
          }

          LifecycleEventObserver 本身就是 LifecycleObserver 的派生,使用時直接 addObserver 到 LivecycleOwner 的 Lifecycle 即可。

          需要在 onStateChanged 中寫 swich / case 自己分發(fā)事件。相對于習慣重寫 Activity 或者 Fragment 的 onCreateonResume 等方法,稍顯啰嗦。

          因此 Lifecycle 給我們準備了 @OnLifecycleEvent 注解

          使用 @OnLifecycleEvent 注解

          使用方法很簡單,繼承 LifecycleObserver 接口,然后在成員方法上添加注解即可

          val?myEventObserver?=?object?:?LifecycleObserver?{

          ????@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
          ????fun?onStart()?{
          ????????TODO()
          ????}

          ????@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
          ????fun?onCreat()?{
          ????????TODO()
          ????}
          }

          添加注冊后,到 LifecycleOwner 的 Event 分發(fā)時,會自動回調(diào)注解匹配的成員方法,由于省去了手動 switch/case 的過程,深受開發(fā)者喜歡

          注解解析過程

          Event 分發(fā)時,怎么就會回到到注解對應(yīng)的方法的?

          通過 addObserver 添加的 LifecycleObserver ,都會轉(zhuǎn)為一個 LifecycleEventObserver ,LifecycleOwner 通過調(diào)用其 onStateChanged 分發(fā) Event

          Lifecycling#lifecycleEventObserver 中處理轉(zhuǎn)換

          public?class?Lifecycling?{
          ????
          ????@NonNull
          ????static?LifecycleEventObserver?lifecycleEventObserver(Object?object)?{
          ????????boolean?isLifecycleEventObserver?=?object?instanceof?LifecycleEventObserver;
          ????????boolean?isFullLifecycleObserver?=?object?instanceof?FullLifecycleObserver;
          ????????//?觀察者是?FullLifecycleObserver
          ????????if?(isLifecycleEventObserver?&&?isFullLifecycleObserver)?{
          ????????????return?new?FullLifecycleObserverAdapter((FullLifecycleObserver)?object,
          ????????????????????(LifecycleEventObserver)?object);
          ????????}

          ????????//?觀察者是?LifecycleEventObserver
          ????????if?(isFullLifecycleObserver)?{
          ????????????return?new?FullLifecycleObserverAdapter((FullLifecycleObserver)?object,?null);
          ????????}

          ????????if?(isLifecycleEventObserver)?{
          ????????????return?(LifecycleEventObserver)?object;
          ????????}

          ????????final?Class?klass?=?object.getClass();
          ????????int?type?=?getObserverConstructorType(klass);

          ????????//?觀察者是通過?apt?產(chǎn)生的類
          ????????if?(type?==?GENERATED_CALLBACK)?{
          ????????????List>?constructors?=
          ????????????????????sClassToAdapters.get(klass);
          ????????????if?(constructors.size()?==?1)?{
          ????????????????GeneratedAdapter?generatedAdapter?=?createGeneratedAdapter(
          ????????????????????????constructors.get(0),?object);
          ????????????????return?new?SingleGeneratedAdapterObserver(generatedAdapter);
          ????????????}
          ????????????GeneratedAdapter[]?adapters?=?new?GeneratedAdapter[constructors.size()];
          ????????????for?(int?i?=?0;?i?????????????????adapters[i]?=?createGeneratedAdapter(constructors.get(i),?object);
          ????????????}
          ????????????return?new?CompositeGeneratedAdaptersObserver(adapters);
          ????????}
          ????????
          ????????//?觀察者需要通過反射生成一個?wrapper
          ????????return?new?ReflectiveGenericLifecycleObserver(object);
          ????}

          ????...

          ????public?static?String?getAdapterName(String?className)?{
          ????????return?className.replace(".",?"_")?+?"_LifecycleAdapter";
          ????}
          }

          邏輯很清晰,根據(jù) LifecycleObserver 類型不用轉(zhuǎn)成不同的 LifecycleEventObserver,

          用一段偽代碼梳理如下:

          if?(lifecycleObserver?is?FullLifecycleObserver)?{
          ??return?FullLifecycleObserverAdapter?//?后文介紹
          }?else?if?(lifecycleObserver?is?LifecycleEventObserver)?{
          ??return?this
          }?else?if?(type?==?GENERATED_CALLBACK)?{
          ??return?GeneratedAdaptersObserver
          }?else?{//?type?==?REFLECTIVE_CALLBACK
          ??return?ReflectiveGenericLifecycleObserver
          }

          注解有兩種使用用途。

          場景一:runtime 時期使用反射生成 wrapper

          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);
          ????}
          }

          CallbackInfo 是關(guān)鍵,通過反射收集當前 LifecycleObserver 的回調(diào)信息。onStateChanged 中通過反射調(diào)用時,不會因為因為缺少 method 報錯。

          場景二:編譯時使用 apt 生成 className + _LifecycleAdapter

          除了利用反射, Lifecycle 還提供了 apt 方式處理注解。

          添加 gradle 依賴:

          dependencies?{
          ????//?java?寫法
          ????annotationProcessor?"androidx.lifecycle:lifecycle-compiler:2.3.1"
          ????//?kotlin?寫法
          ????kapt?"androidx.lifecycle:lifecycle-compiler:2.3.1"
          }

          這樣在編譯器就會根據(jù) LifecyceObserver 類名生成一個添加 _LifecycleAdapter 后綴的類。比如我們加了 onCreatonStart 的注解,生成的代碼如下:

          public?class?MyEventObserver_LifecycleAdapter?implements?GeneratedAdapter?{
          ??final?MyEventObserver?mReceiver;

          ??MyEventObserver_LifecycleAdapter(MyEventObserver?receiver)?{
          ????this.mReceiver?=?receiver;
          ??}

          ??@Override
          ??public?void?callMethods(LifecycleOwner?owner,?Lifecycle.Event?event,?boolean?onAny,
          ??????MethodCallsLogger?logger)
          ?
          {
          ????boolean?hasLogger?=?logger?!=?null;
          ????if?(onAny)?{
          ??????return;
          ????}
          ????if?(event?==?Lifecycle.Event.ON_CREATE)?{
          ??????if?(!hasLogger?||?logger.approveCall("onCreate",?1))?{
          ????????mReceiver.onCreate();
          ??????}
          ??????return;
          ????}
          ????if?(event?==?Lifecycle.Event.ON_START)?{
          ??????if?(!hasLogger?||?logger.approveCall("onStart",?1))?{
          ????????mReceiver.onStart();
          ??????}
          ??????return;
          ????}
          ??}
          }

          apt 減少了反射的調(diào)用,性能更好,當然會犧牲一些編譯速度。

          為什么要使用注解

          生命周期的 Event 種類很多,我們往往不需要全部實現(xiàn),如過不使用注解,可能需要實現(xiàn)所有方法,產(chǎn)生額外的無用代碼

          上面代碼中的 FullLifecycleObserver 就是一個全部方法的接口

          interface?FullLifecycleObserver?extends?LifecycleObserver?{

          ????void?onCreate(LifecycleOwner?owner);

          ????void?onStart(LifecycleOwner?owner);

          ????void?onResume(LifecycleOwner?owner);

          ????void?onPause(LifecycleOwner?owner);

          ????void?onStop(LifecycleOwner?owner);

          ????void?onDestroy(LifecycleOwner?owner);
          }

          從接口不是 public 的( java 代碼 ) 可以看出,官方也無意讓我們使用這樣的接口,增加開發(fā)者負擔。

          遭廢棄的原因

          既然注解這么好,為什么又要廢棄呢?

          This annotation required the usage of code generation or reflection, which should be avoided.

          從官方文檔的注釋可以看到,注解要么依賴反射降低運行時性能,要么依靠 APT 降低編譯速度,不是完美的方案。

          我們之所引入注解,無非是不想多實現(xiàn)幾個空方法。早期 Android 工程不支持 Java8 編譯,接口沒有 default 方法, 現(xiàn)如今 Java8 已經(jīng)是默認配置,可以為接口添加 default 方法,此時注解已經(jīng)失去了存在的意義。

          如今官方推薦使用 DefaultLifecycleObserver 接口來定義你的 LifecycleObserver

          public?interface?DefaultLifecycleObserver?extends?FullLifecycleObserver?{

          ????@Override
          ????default?void?onCreate(@NonNull?LifecycleOwner?owner)?{
          ????}

          ????@Override
          ????default?void?onStart(@NonNull?LifecycleOwner?owner)?{
          ????}

          ????@Override
          ????default?void?onResume(@NonNull?LifecycleOwner?owner)?{
          ????}

          ????@Override
          ????default?void?onPause(@NonNull?LifecycleOwner?owner)?{
          ????}

          ????@Override
          ????default?void?onStop(@NonNull?LifecycleOwner?owner)?{
          ????}

          ????@Override
          ????default?void?onDestroy(@NonNull?LifecycleOwner?owner)?{
          ????}
          }

          FullLifecycleObserverAdapter, 無腦回調(diào) FullLifecycleObserver 即可

          class?FullLifecycleObserverAdapter?implements?GenericLifecycleObserver?{

          ????private?final?FullLifecycleObserver?mObserver;

          ????FullLifecycleObserverAdapter(FullLifecycleObserver?observer)?{
          ????????mObserver?=?observer;
          ????}

          ????@Override
          ????public?void?onStateChanged(LifecycleOwner?source,?Lifecycle.Event?event)?{
          ????????switch?(event)?{
          ????????????case?ON_CREATE:
          ????????????????mObserver.onCreate(source);
          ????????????????break;
          ????????????case?ON_START:
          ????????????????mObserver.onStart(source);
          ????????????????break;
          ????????????case?ON_RESUME:
          ????????????????mObserver.onResume(source);
          ????????????????break;
          ????????????case?ON_PAUSE:
          ????????????????mObserver.onPause(source);
          ????????????????break;
          ????????????case?ON_STOP:
          ????????????????mObserver.onStop(source);
          ????????????????break;
          ????????????case?ON_DESTROY:
          ????????????????mObserver.onDestroy(source);
          ????????????????break;
          ????????????case?ON_ANY:
          ????????????????throw?new?IllegalArgumentException("ON_ANY?must?not?been?send?by?anybody");
          ????????}
          ????}
          }

          需要注意 DefaultLifecycleObserver 在 2.4.0 之前也是可以使用的, 存在于 androidx.lifecycle.lifecycle-common-java8 這個庫中, 2.4.0 開始 統(tǒng)一移動到 androidx.lifecycle.lifecycle-common 了 ,已經(jīng)沒有 java8 單獨的擴展庫了。



          ? 耗時2年,Android進階三部曲第三部《Android進階指北》出版!

          ? 『BATcoder』做了多年安卓還沒編譯過源碼?一個視頻帶你玩轉(zhuǎn)!

          ? 『BATcoder』我去!安裝Ubuntu還有坑?

          ? 重生!進階三部曲第一部《Android進階之光》第2版 出版!

          為了防止失聯(lián),歡迎關(guān)注我的小號

          ??微信改了推送機制,真愛請星標本公號??
          瀏覽 120
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉美女视频 | 日韩精品导航 | 男人先锋资源网 | 国产尤物在线 | 亚洲欧洲AⅤ |