android官方架构组件,Android 架构组件官方文档01——LifeCycle
使用生命周期感知組件處理生命周期
支持生命周期的組件執(zhí)行操作以響應另一個組件(例如Activity和fragment)的生命周期狀態(tài)更改。這些組件可幫助您生成組織性更好,并且通常更輕量的代碼,這些代碼更易于維護。
常見的模式是在Activity和fragment的生命周期方法中實現依賴組件的操作。
但是,這種模式導致代碼的組織不良以及錯誤泛濫。通過使用生命周期感知組件,您可以將相關組件的代碼從生命周期方法中移出并移入組件本身。
android.arch.lifecycle包提供了類和接口,可讓您構建支持生命周期的組件,這些組件可根據活動或片段的當前生命周期狀態(tài)自動調整其行為
Android框架中定義的大多數應用程序組件都附帶有生命周期。生命周期由操作系統(tǒng)或您的流程中運行的框架代碼管理。它們是Android如何工作和應用程序必須尊重它們的核心。不這樣做可能會觸發(fā)內存泄漏甚至應用程序崩潰。
// 如果使用的是java 8要顯示聲明如下的
def lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
想象一下,我們有一個在屏幕上顯示設備位置的Activity。
常見的實現可能如下所示:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// connect to system location service
}
void stop() {
// disconnect from system location service
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// update UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
// manage other components that need to respond
// to the activity lifecycle
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
// manage other components that need to respond
// to the activity lifecycle
}
}
盡管這個示例看起來很好,但在實際的應用程序中,您最終會有太多的調用來管理UI和其他組件,以響應當前的生命周期狀態(tài)。
管理多個組件會在生命周期方法中放置大量代碼,例如onStart()和onStop(),這使得它們很難維護。
此外,無法保證組件在活動或片段停止之前啟動。
如果我們需要執(zhí)行一個長時間運行的操作,比如onStart()中的一些配置檢查,情況尤其如此。
這可能會導致onStop()方法在onStart()之前完成的爭用條件,從而使組件的存活時間超過所需的時間。
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// update UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// what if this callback is invoked AFTER activity is stopped?
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
android.arch.lifecycle包提供的類和接口可幫助您以彈性和獨立的方式解決這些問題。
Lifecycle
Lifecycle是一個持有組件生命周期狀態(tài)(如Activity或Fragment)的信息的類,并允許其他對象觀察此狀態(tài)。
Lifecycle使用兩個主要枚舉來跟蹤其關聯組件的生命周期狀態(tài):
Event
從框架和Lifecycle類派發(fā)的生命周期事件。
這些事件映射到Activities和fragments中的回調事件。
State
由Lifecycle對象跟蹤的組件的當前狀態(tài)。
將狀態(tài)視為圖中的節(jié)點,將事件視為這些節(jié)點之間的邊界。
一個類可以通過向其方法添加注解來監(jiān)視組件的生命周期狀態(tài)。
然后,您可以通過調用Lifecycle類的addObserver()方法并傳遞觀察者的實例來添加觀察者,如下例所示:
public class MyObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
在上面的例子中,myLifecycleOwner對象實現了LifecycleOwner接口,這將在下一節(jié)中介紹。
LifecycleOwner
LifecycleOwner是一個單一的方法接口,表示該類有一個Lifecycle。
它有一個方法getLifecycle(),它必須由class實現。
如果您試圖管理整個應用程序進程的生命周期,請參閱ProcessLifecycleOwner。
該接口從各個類(如Fragment和AppCompatActivity)抽象生命周期的所有權,并允許編寫與它們一起工作的組件。
任何自定義應用程序類都可以實現LifecycleOwner接口
實現LifecycleObserver的組件可以與實現LifecycleOwner的組件無縫協(xié)作,因為所有者可以提供生命周期,觀察者可以注冊觀察。
對于位置跟蹤示例,我們可以使MyLocationListener類實現LifecycleObserver,然后使用onCreate()方法中的活動生命周期對其進行初始化。
這允許MyLocationListener類是自給自足的,這意味著對生命周期狀態(tài)變化作出反應的邏輯在MyLocationListener中聲明,而不是在活動中聲明。
讓各個組件存儲自己的邏輯使得活動和片段邏輯更容易管理。
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
// update UI
});
Util.checkUserStatus(result -> {
if (result) {
myLocationListener.enable();
}
});
}
}
一個常見的用例就是避免在生命周期狀處于不好的狀態(tài)時調用某些回調。
例如,如果回調在保存活動狀態(tài)后(我自己理解為onSaveInstanceState()方法執(zhí)行后,也就是fragment不存在)運行fragment事務,則會觸發(fā)崩潰,因此我們絕不希望調用該回調。
為了簡化這個用例,生命周期類允許其他對象查詢當前狀態(tài)。
class MyLocationListener implements LifecycleObserver {
private boolean enabled = false;
public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
if (enabled) {
// connect
}
}
public void enable() {
enabled = true;
if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
// connect if not connected
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// disconnect if connected
}
}
通過這個實現,我們的LocationListener類完全是生命周期感知的。
如果我們需要使用來自其他Activity或Fragment的LocationListener,我們只需要初始化它。
所有的啟動和銷毀操作都由該類本身進行管理。
如果Library提供需要與Android生命周期配合使用的類,我們建議您使用支持生命周期的組件。
您的Library客戶端可以在客戶端無需手動生命周期管理即可輕松集成這些組件。
實施自定義LifecycleOwner
Support Library 26.1.0中的Fragment和Activity以及更高版本已經實現LifecycleOwner接口。
如果您想要創(chuàng)建LifecycleOwner的自定義類,則可以使用LifecycleRegistry類,但需要將事件轉發(fā)到該類中,如以下代碼示例所示:
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLifecycleRegistry = new LifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
public void onStart() {
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
生命周期感知組件的最佳實踐
盡可能保持您的UI控制器(Activities和Fragments)盡可能精簡。他們不應該試圖獲取他們自己的數據;相反,使用ViewModel來做到這一點,并觀察一個LiveData對象來反映更改回視圖。
嘗試編寫數據驅動UI的界面,其中您的UI控制器的職責是在數據更改時更新視圖,或將用戶操作通知給ViewModel。
把你的數據邏輯放在ViewModel類中。ViewModel應作為您的UI控制器和其他應用程序之間的連接器。但要小心,ViewModel不負責提取數據(例如,來自網絡)。相反,ViewModel應調用相應的組件來獲取數據,然后將結果提供給UI控制器。
使用Data Binding在視圖和UI控制器之間保持干凈的界面。這使您可以使您的視圖更具說明性,并最大限度地減少需要在活動和片段中編寫的更新代碼。如果你喜歡用Java編程語言來做到這一點,可以使用像Butter Knife這樣的庫來避免樣板代碼并且有更好的抽象
如果您的UI很復雜,請考慮創(chuàng)建一個presenter類來處理UI修改。這可能是一項艱巨的任務,但它可以使您的UI組件更易于測試。
避免在ViewModel中引用View或Activity上下文。如果ViewModel超出活動(在配置更改的情況下),則活動會泄漏并且垃圾收集器無法正確處理。
支持生命周期感知組件的用例
支持生命周期的組件可以讓您在各種情況下更容易地管理生命周期。
一些例子是:
在粗粒度和細粒度 位置更新之間切換。使用生命周期感知組件在位置應用可見時啟用細粒度位置更新,并在應用處于后臺時切換到粗粒度更新。LiveData是一種生命周期感知型組件,允許您的應用在用戶更改位置時自動更新用戶界面。
停止并開始視頻緩沖。盡可能使用支持生命周期的組件來啟動視頻緩沖,但延遲播放直到應用程序完全啟動。您還可以使用生命周期感知組件在應用程序銷毀時終止緩沖。
啟動和停止網絡連接。使用支持生命周期的組件可以在應用程序處于前臺時實時更新(流式傳輸)網絡數據,并在應用程序進入后臺時自動暫停。
暫停和恢復動畫可繪制。使用生命周期感知組件處理在應用程序處于后臺時暫停動畫的可繪制畫面,并在應用程序處于前景時恢復可繪制畫面。
處理停止事件
當Lifecycle屬于AppCompatActivity或Fragment時,Lifecycle的狀態(tài)將更改為CREATED,并在調用AppCompatActivity或Fragment的onSaveInstanceState()時調度ON_STOP事件。
當Fragment或AppCompatActivity的狀態(tài)通過onSaveInstanceState()保存時,UI被認為是不可變的,直到ON_START被調用。嘗試在保存狀態(tài)后修改UI界面可能會導致應用程序的導航狀態(tài)不一致,這就是為什么如果應用程序在狀態(tài)保存后運行FragmentTransaction時FragmentManager會拋出異常。
有關詳細信息,詳情請參閱 commit()。
如果觀察者的關聯Lifecycle在STARTED之前,則LiveData通過避免調用其觀察者來防止這種邊緣情況出現。
在幕后,它決定調用觀察者之前調用isAtLeast()。
不幸的是,AppCompatActivity的onStop()方法會在onSaveInstanceState()之后調用,這會在不允許UI狀態(tài)更改但生命周期尚未移至CREATED狀態(tài)的情況下留下空隙。
為了防止出現這個問題,beta2版本中的Lifecycle類將lower狀態(tài)標記為CREATED而不分派事件,即使事件直到onStop()被調用也未被分派,任何檢查當前狀態(tài)的代碼也都會獲得真實值。
不幸的是,這個解決方案有兩個主要問題:
在API等級23或更低的情況下,Android系統(tǒng)實際上保存活動的狀態(tài),即使它被另一活動部分覆蓋。換句話說,Android系統(tǒng)調用onSaveInstanceState(),但不一定調用onStop()。這會創(chuàng)建一個潛在的長時間間隔,即使其UI狀態(tài)無??法修改,觀察者仍認為生命周期處于活動狀態(tài)。
任何想要向LiveData類公開類似行為的類都必須實現Lifecycle beta2和更低版本提供的解決方法
注意:為了使此流程更簡單,并提供與舊版本的更好兼容性,從版本1.0.0-rc1開始,在調用onSaveInstanceState()而無需等待對onStop()的調用時,將Lifecycle對象標記為CREATED,并調度onStop()方法。這不太可能影響您的代碼,但您需要注意這一點,因為它與API級別26及更低級別的Activity類中的調用順序不匹配。
總結
以上是生活随笔為你收集整理的android官方架构组件,Android 架构组件官方文档01——LifeCycle的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 婉婷名字的含义 婉婷名字的含义是什么
- 下一篇: android webview file