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