Android Jetpack架構篇:Lifecycles

Android Jetpack架構篇:Lifecycles

使用生命週期感知組件處理生命週期

生命週期感知組件執行操作以響應另一個組件(例如活動和片段)的生命週期狀態的更改。這些組件可幫助您生成更易於組織且通常更輕量級的代碼,這些代碼更易於維護。

一種常見的模式是在活動和片段的生命週期方法中實現依賴組件的操作。但是,這種模式導致代碼組織不良以及錯誤的增加。通過使用生命週期感知組件,您可以將依賴組件的代碼移出生命週期方法並移入組件本身。

該android.arch.lifecycle 包提供了類和接口,使您可以構建生命週期感知 組件 - 這些組件可以根據活動或片段的當前生命週期狀態自動調整其行為。

Android Jetpack架構篇:Lifecycles

Android框架中定義的大多數應用程序組件都附加了生命週期。生命週期由操作系統或流程中運行的框架代碼管理。它們是Android工作原理的核心,您的應用程序必須尊重它們。不這樣做可能會觸發內存洩漏甚至應用程序崩潰。

想象一下,我們有一個活動,在屏幕上顯示設備位置。常見的實現可能如下所示:

Android Jetpack架構篇:Lifecycles

即使這個示例看起來很好,但在真實的應用程序中,最終會有太多的調用來管理UI和其他組件以響應生命週期的當前狀態。管理多個組件會在生命週期方法中放置大量代碼,例如

onStart()onStop(),這使得它們難以維護。

此外,無法保證組件在活動或片段停止之前啟動。如果我們需要執行長時間運行的操作(例如某些配置檢入),則尤其如此onStart()。這可能導致競爭條件,其中onStop()方法在之前完成onStart(),使組件保持活動的時間長於其所需的時間。

Android Jetpack架構篇:Lifecycles

android.arch.lifecycle 軟件包提供了類和接口,可幫助您以彈性和隔離的方式解決這些問題。

Lifecycle

Lifecycle 是一個類,它包含有關組件生命週期狀態的信息(如活動或片段),並允許其他對象觀察此狀態。

Lifecycle 使用兩個主要枚舉來跟蹤其關聯組件的生命週期狀態:

Event(事件)

從框架和Lifecycle類調度的生命週期事件 。這些事件映射到活動和片段中的回調事件。

State(狀態)

Android Jetpack架構篇:Lifecycles

將狀態視為圖形的節點,將事件視為這些節點之間的邊緣。

類可以通過向其方法添加註釋來監視組件的生命週期狀態。然後,您可以通過調用 類的 addObserver() 方法Lifecycle並傳遞觀察者的實例來添加觀察者,如以下示例所示:

Android Jetpack架構篇:Lifecycles

在上面的示例中,

myLifecycleOwner對象實現了 LifecycleOwner 接口,將在下一節中進行說明。

LifecycleOwner

LifecycleOwner 是一個單一的方法接口,表示該類有一個 Lifecycle。它有一個方法, getLifecycle() 必須由類實現。如果您正在嘗試管理整個應用程序流程的生命週期,請參閱 ProcessLifecycleOwner

此接口Lifecycle從各個類(例如Fragment和)中抽象出所有權 AppCompatActivity,並允許編寫與其一起使用的組件。任何自定義應用程序類都可以實現LifecycleOwner 接口。

與實現的組件LifecycleObserver 無縫實現 工作的組件, LifecycleOwner 因為所有者可以提供生命週期,觀察者可以註冊觀察。

對於位置跟蹤的例子,我們可以使MyLocationListener類實現LifecycleObserver ,然後用活動的初始化 LifecycleonCreate()方法。這允許 MyLocationListener類自給自足,這意味著響應生命週期狀態變化的邏輯被聲明MyLocationListener而不是活動。使各個組件存儲自己的邏輯使得活動和片段邏輯更易於管理。

Android Jetpack架構篇:Lifecycles

一個常見的用例是,如果Lifecycle現在不處於良好狀態,則應避免調用某些回調 。例如,如果回調在保存活動狀態後運行片段事務,則會觸發崩潰,因此我們永遠不會想要調用該回調。

為了簡化這個用例,Lifecycle該類允許其他對象查詢當前狀態。

Android Jetpack架構篇:Lifecycles

通過這種實現,我們的

LocationListener類完全可以識別生命週期。如果我們需要使用LocationListener另一個活動或片段,我們只需要初始化它。所有設置和拆卸操作都由類本身管理。

如果庫提供了需要使用Android生命週期的類,我們建議您使用生命週期感知組件。您的庫客戶端可以輕鬆地集成這些組件,而無需在客戶端進行手動生命週期管理。

實現自定義LifecycleOwner

支持庫26.1.0及更高版本中的片段和活動已實現該LifecycleOwner 接口。

如果您要創建自定義類,則 LifecycleOwner可以使用 LifecycleRegistry 類,但需要將事件轉發到該類,如以下代碼示例所示:

Android Jetpack架構篇:Lifecycles

生命週期感知組件的最佳實踐

  • 保持UI控制器(活動和片段)儘可能精簡。他們不應該試圖獲取自己的數據; 相反,使用a ViewModel執行此操作,並觀察LiveData 對象以將更改反映回視圖。
  • 嘗試編寫數據驅動的UI,您的UI控制器負責在數據更改時更新視圖,或者將用戶操作通知給 ViewModel
  • 把你的數據邏輯放在你的 ViewModel班級。 ViewModel應該作為UI控制器和應用程序其餘部分之間的連接器。但要小心,ViewModel獲取數據(例如,從網絡)是沒有 責任的。相反, ViewModel應該調用適當的組件來獲取數據,然後將結果提供回UI控制器。
  • 使用數據綁定來維護視圖和UI控制器之間的乾淨界面。這使您可以使視圖更具聲明性,並最大限度地減少在活動和片段中編寫所需的更新代碼。如果您更喜歡使用Java編程語言執行此操作,請使用Butter Knife之類的庫 來避免樣板代碼並具有更好的抽象。
  • 如果您的UI很複雜,請考慮創建一個 presenter 類來處理UI修改。這可能是一項艱鉅的任務,但它可以使您的UI組件更容易測試。
  • 避免引用 你的內容ViewActivity上下文ViewModel。如果ViewModel活動超過活動(在配置更改的情況下),您的活動將洩漏並且垃圾收集器未正確處理。

生命週期感知組件的用例

生命週期感知組件可以使您在各種情況下更輕鬆地管理生命週期。一些例子是:

  • 在粗粒度和細粒度位置更新之間切換。使用生命週期感知組件可在您的位置應用程序可見時啟用細粒度位置更新,並在應用程序位於後臺時切換到粗粒度更新。LiveData,一個生命週期感知組件,允許您的應用在用戶更改位置時自動更新UI。
  • 停止並開始視頻緩衝。使用生命週期感知組件儘快啟動視頻緩衝,但推遲播放直到應用程序完全啟動。您還可以使用生命週期感知組件在銷燬應用程序時終止緩衝。
  • 啟動和停止網絡連接。使用生命週期感知組件在應用程序處於前臺時啟用網絡數據的實時更新(流式傳輸),並在應用程序進入後臺時自動暫停。
  • 暫停和恢復動畫drawables。當應用程序在後臺時,使用生命週期感知組件處理暫停動畫可繪製的內容,並在應用程序位於前臺後恢復可繪製內容。

處理停止事件

當一個Lifecycle屬於一個AppCompatActivityFragment,所述Lifecycle的狀態改變為 CREATED與所述ON_STOP 事件被調度時AppCompatActivityFragmentonSaveInstanceState() 被調 用。

當一個Fragment或者AppCompatActivity的狀態被保存時

onSaveInstanceState(),它的UI在ON_START 被調用之前被認為是不可變的 。保存狀態後嘗試修改UI可能會導致應用程序的導航狀態不一致,這就是為什麼FragmentManager 在應用程序運行FragmentTransaction 保存後狀態時會拋出異常的 原因。詳情 commit()請見。

LiveData如果觀察者的關聯Lifecycle 不是至少 ,則通過避免調用其觀察者來防止這種邊緣情況開箱即用STARTED。在幕後,它 isAtLeast() 在決定調用其觀察者之前調用。

不幸的是,AppCompatActivityonStop() 方法被調用後 onSaveInstanceState(),留下其中UI狀態,但不允許更改,但差距 Lifecycle 還沒有移動到 CREATED 狀態。

為防止出現此問題,

Lifecycle 版本beta2 和較低的類將狀態標記為 CREATED 不調度事件,以便檢查當前狀態的任何代碼都獲得實際值,即使事件未被調度,直到onStop() 系統調用。

不幸的是,這個解決方案有兩個主要問題

  • 在API級別23和更低級別,Android系統實際上保存了活動的狀態,即使它被另一個活動部分覆蓋。換句話說,Android系統調用onSaveInstanceState() 但不一定要調用onStop()。這會創建一個潛在的長間隔,即使無法修改其UI狀態,觀察者仍然認為生命週期處於活動狀態。
  • 任何想要向類公開類似行為的 LiveData類都必須實現Lifecycleversion beta 2和lower 提供的解決方法 。
Android Jetpack架構篇:Lifecycles

-----點擊上方關注持續收聽面試乾貨

Android Jetpack架構篇:Lifecycles

私信 “666” 索要Android高級視頻(Flutter進階,插件化,熱修復技術)

加群(960865742)


分享到:


相關文章: