什么是Android Jetpack悼沈?
Android Jetpack是谷歌在2018年I/O開發(fā)者大會上推出的新一代組件、工具和架構(gòu)指導(dǎo),旨在加快開發(fā)者的 Android 應(yīng)用開發(fā)速度。 ——官方介紹網(wǎng)站
Android Jetpack 組件是庫的集合窘游,這些庫是為協(xié)同工作而構(gòu)建的,不過也可以單獨(dú)采用跳纳,同時利用 Kotlin 語言功能幫助您提高工作效率忍饰。可全部使用寺庄,也可混合搭配艾蓝!
Android Jetpack組件的優(yōu)勢:
Jetpack推出的主要目的是為了能夠讓開發(fā)者更加快速、方便以及高質(zhì)量的完成產(chǎn)品開發(fā)
- 輕松管理應(yīng)用程序的生命周期斗塘,后臺任務(wù)的管理赢织,導(dǎo)航的處理等等
- 利用Jetpack組件進(jìn)行開發(fā)可以有效減少內(nèi)存溢出、崩潰的概率馍盟,提升應(yīng)用開發(fā)的質(zhì)量
Jetpack組件主要分為四個方向:基礎(chǔ)于置,架構(gòu),行為和UI贞岭。詳情見下
Android Jetpack組件推薦的使用項(xiàng)目架構(gòu)
上面架構(gòu)組件的功能如下:
- Activity和Fragment負(fù)責(zé)產(chǎn)品與用戶的交互
- ViewModel作為數(shù)據(jù)的存儲和驅(qū)動
- Resposity負(fù)責(zé)調(diào)度數(shù)據(jù)的獲劝颂骸(Room儲存本地序列化的數(shù)據(jù),Retrofit獲取遠(yuǎn)程數(shù)據(jù)的數(shù)據(jù))
ViewModel+ LiveData
ViewModel的優(yōu)點(diǎn):
- 解決了運(yùn)行中斷和界面重建時的數(shù)據(jù)保存問題 (橫豎屏切換瞄桨,導(dǎo)致Activity銷毀并重新創(chuàng)建時话速,ViewMode仍然可以保留之前讀取到的數(shù)據(jù)不會因?yàn)锳ctivity的銷毀而丟失,這樣我們無需額外再浪費(fèi)資源去再次請求數(shù)據(jù))
- 配合LiveData實(shí)時獲取最新數(shù)據(jù)
- 實(shí)現(xiàn)Activity中Fragment之間的數(shù)據(jù)交互(數(shù)據(jù)共享)
- 數(shù)據(jù)和界面的分離讲婚,使數(shù)據(jù)驅(qū)動界面 (ViewModel類被設(shè)計(jì)為通過lifecycle感知的方式存儲和管理UI相關(guān)數(shù)據(jù))
ViewModel的生命周期:
- ViewModel對象的范圍是在獲取ViewModel時傳遞給ViewModelProvider的Lifecycle生命周期
- ViewModel在內(nèi)存中直到Activity銷毀或Fragment被移除
- 系統(tǒng)首次調(diào)用活動對象的onCreate()方法時尿孔,通常會請求ViewModel
- 系統(tǒng)可能會在整個活動的整個生命周期中多次調(diào)用onCreate(),例如當(dāng)設(shè)備屏幕旋轉(zhuǎn)時
- ViewModel從第一次請求ViewModel直到活動完成并銷毀時存在
ViewMode在其生命周期的范圍內(nèi)會一直保存在內(nèi)存中筹麸,所以橫豎屏切換 當(dāng)切換手機(jī)橫豎屏后,Activity會destroy并重新onCreate來重構(gòu)當(dāng)前界面雏婶,生命周期再次重新觸發(fā)onCreate物赶,但是ViewMode 并沒有重新執(zhí)行獲取數(shù)據(jù)的操作。
由于 ViewModel 生命周期可能長與 activity 生命周期留晚,所以為了避免內(nèi)存泄漏 Google 禁止在 ViewModel 中持有 Context 或 activity 或 view 的引用酵紫。
如果有些請求數(shù)據(jù)的情況必須用到Context告嘲,在繼承ViewMode的時候,可以改為繼承AndroidViewMode奖地,這個類會返回一個帶有Context的構(gòu)造函數(shù)橄唬。
ViewMode執(zhí)行onCleared操作,這個是ViewMode的一個回調(diào)参歹,表明當(dāng)前Activity要徹底關(guān)閉仰楚,ViewMode需要做一些回收清理的操作
LiveData
優(yōu)點(diǎn):
- 確保UI界面的數(shù)據(jù)狀態(tài)
- 沒有內(nèi)存泄漏,不會因?yàn)锳ctivity的不可見導(dǎo)致Crash
- 一個存放可被觀察的數(shù)據(jù)持有類,但與一般的被觀察者不同的是犬庇,它是有生命周期感知功能僧界,解決了android開發(fā)者需要去手動處理生命周期的痛點(diǎn)。
- 共享資源
viewMode.getUserLiveData().observe(this, new Observer<String>() {
@Override
public void onChanged(String users) {
fragment2.setText("fragment2==\n" + users);
}
});
LiveData是一個observable數(shù)據(jù)持有類,LiveData是生命周期感知的臭挽,這意味著它跟隨其他應(yīng)用程序組件(如activities, fragments, or services)的生命周期捂襟。這種感知能力確保LiveData只更新處于活躍生命周期狀態(tài)的應(yīng)用程序組件
LiveData與一個Observer關(guān)聯(lián),如果觀察者的生命周期處于STARTED或RESUMED狀態(tài)欢峰,則表示觀察者處于活動狀態(tài)葬荷。LiveData只通知活躍的觀察者做更新。注冊到LiveData對象中的不活躍的觀察者則得不到數(shù)據(jù)更新的通知纽帖。
注冊一個observer并與實(shí)現(xiàn)了LifecycleOwner接口的對象配對宠漩。這種關(guān)系允許當(dāng)相應(yīng)的Lifecycle對象的狀態(tài)改變?yōu)镈ESTROYED時,觀察者被移除
利用ViewMode(配合LiveData實(shí)時獲取最新數(shù)據(jù))進(jìn)行Fragment之間的數(shù)據(jù)交互
public class OneFragment extends BaseFragment {
@BindView(R2.id.fragment2)
TextView fragment2;
@Override
protected int initLayout() {
return R.layout.fragment_detail;
}
@Override
protected void initView(View view) {
//綁定ViewMode的selected的值抛计,當(dāng)有更新時通知DetailFragment
SharedViewModel viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
viewMode.getUserLiveData().observe(this, new Observer<String>() {
@Override
public void onChanged(String users) {
fragment2.setText("fragment2==\n" + users);
}
});
}
}
public class TwoFragment extends BaseFragment {
@BindView(R2.id.fragment1)
TextView fragment1;
SharedViewModel viewMode;
@Override
protected void initView(View view) {
//注意:這里ViewModelProviders.of(getActivity())這里的參數(shù)需要是Activity哄孤,而不能是Fragment,否則收不到監(jiān)聽
viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
fragment1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//當(dāng)點(diǎn)擊某一個item的時候吹截,更新viewmode中的selected的值
viewMode.select("fragment1點(diǎn)擊后瘦陈,更新viewmode中的值,fragment2 里面的數(shù)據(jù)同步更新");
}
});
}
@Override
protected void initData() {
viewMode.getUserLiveData().observe(this, new Observer<String>() {
@Override
public void onChanged(String users) {
Log.w("TAG", "====" + users);
}
});
}
@Override
protected int initLayout() {
return R.layout.fragment_master;
}
}
public class SharedViewModel extends AndroidViewModel {
//userLiveData保存的是被選中的item的狀態(tài)或者數(shù)據(jù)
private MutableLiveData<String> userLiveData;
public MutableLiveData<String> getUserLiveData() {
if (userLiveData == null) {
Log.w("TAG", "SharedViewModel-getUserLiveData");
userLiveData = new MutableLiveData<>();
}
return userLiveData;
}
//主要通過masterFragment進(jìn)行調(diào)用交互波俄,用來更新selected中的值
public void select(String item) {
userLiveData.setValue(item);
}
public SharedViewModel(@NonNull Application application) {
super(application);
}
/**
* 這里可以執(zhí)行一些資源釋放晨逝、數(shù)據(jù)清理的操作
* ViewMode會執(zhí)行onCleared操作,這個是ViewMode的一個回調(diào)懦铺,
* 表明當(dāng)前Activity要徹底關(guān)閉捉貌,ViewMode需要做一些回收清理的操作,如下代碼:
*/
@Override
protected void onCleared() {
super.onCleared();
}
}
上述代碼的邏輯很簡單冬念,OneFragment與TwoFragment并不直接進(jìn)行交互趁窃,而是各自與ViewMode進(jìn)行交互,OneFragment用來更新維護(hù)ViewMode中的數(shù)據(jù)急前,TwoFragment可以收到來自ViewMode中數(shù)據(jù)更新的通知醒陆。這樣便達(dá)到了兩個frangment之間的數(shù)據(jù)通信。
LifeCycles原理
Lifecycles是生命周期管理組件 另一組件的生命周期狀態(tài)(隨著Activity和Fragment)的變化而執(zhí)行動作裆针,support 26 以上的兼容包中的AppCompatActivity與Fragment中默認(rèn)已實(shí)現(xiàn)了LifeCycleOwner接口刨摩,保證了LiveData及ViewModel具備了生命周期感知與內(nèi)存緩存的能力寺晌。
場景使用:在平時的開發(fā)過程中,我們難免有些邏輯的執(zhí)行是和UI的生命周期相結(jié)合的澡刹,需要在特定的生命周期中執(zhí)行相應(yīng)的方法呻征,我們平時做的可能就是在View中的每個周期調(diào)用Present中獲取數(shù)據(jù)的方法,然后在調(diào)用View的回調(diào)接口更新UI罢浇,但現(xiàn)在使用Lifecycles可以使用注解和觀察的模式自動調(diào)用Observe中定義好的方法陆赋。
//誰觀察生命周期 就注冊誰 兩個角色定義好后,需要讓他們之間建立聯(lián)系
//獲取Lifecycle
getLifecycle().addObserver(new LocationListener());
public class LocationListener implements LifecycleObserver {
private static final String TAG = "TAG";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onActivityCreate(LifecycleOwner owner) {
Log.w(TAG, "onActivityCreate");
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onActivityDestroy(LifecycleOwner owner) {
Log.w(TAG, "onActivityDestroy");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onActivityPause(LifecycleOwner owner) {
Log.w(TAG, "onActivityPause");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onActivityResume(LifecycleOwner owner) {
Log.w(TAG, "onActivityResume");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onActivityStart(LifecycleOwner owner) {
Log.w(TAG, "onActivityStart");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onActivityStop(LifecycleOwner owner) {
Log.w(TAG, "onActivityStop");
}
}
Lifecycle 原理 如何感知 activity 或 fragment 生命周期
1己莺、activity 和 fragment 已經(jīng)實(shí)現(xiàn)了 LifecycleOwner
2奏甫、出現(xiàn)了一個LifecycleRegistry,是 Lifecycle 的一個實(shí)現(xiàn)類凌受。通過markState方法在onSaveInstanceState把 Lifecycle 狀態(tài)標(biāo)記為Lifecycle.State.CREATED阵子。
3、onCreate 方法里有個ReportFragment胜蛉,
4挠进、利用 fragment 的特性,綁定了一個 fragment 然后在其生命周期dispatch()方法中調(diào)用了LifecycleRegistry的handleLifecycleEvent誊册,此方法便是通知觀察者的地方领突。Lifecycle.Event,判斷執(zhí)行事件后下一個到達(dá)的狀態(tài)案怯,然后使用moveToState()中修改活動的生命周期
5君旦、通知觀察者addObserver 后,把observer維護(hù)到ObserverWithState然后裝到 map 里嘲碱。
然后通過handleLifecycleEvent方法最終遍歷map 通知 observer金砍。
偽代碼
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
}
ViewModel 原理
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
ViewModel 和 onSaveInstaceState方法區(qū)別在于:ViewModel只能保存因?yàn)榕渲酶膶?dǎo)致重建的數(shù)據(jù),但是它能保存大量和復(fù)雜的數(shù)據(jù)麦锯;onSaveInstaceState能保存配置更改導(dǎo)致重建和資源限制導(dǎo)致重建的數(shù)據(jù)恕稠,但是它只能保存少量簡單的數(shù)據(jù)。ViewModel使用SavedStateHandle能夠保存資源限制導(dǎo)致重建的數(shù)據(jù)扶欣。
根據(jù)傳入的Activity獲取鹅巍、創(chuàng)建、添加并以鍵值對保存Fragment料祠,從VIewStore的Map中或Factory的create()中獲取ViewMode
1骆捧、獲取ViewProvider:
2、獲取ViewModelStore:由前面的源碼可以知道創(chuàng)建ViewProvider時傳入兩個參數(shù):ViewModelStore 和 Factory髓绽;顯然從名字就可以看出他們的作用凑懂,F(xiàn)actory負(fù)責(zé)創(chuàng)建,ViewModelStore負(fù)責(zé)存儲
ViewModelStore內(nèi)部維護(hù)者一個Map集合保存者ViewModel對象的鍵值對
ViewModel的生命周期要比Activity長一點(diǎn)梧宫。因?yàn)樵贑omponentActivity 實(shí)現(xiàn)了的getViewModelStore 接谨,ViewModelStore在Activity重建前后能保持同一個對象就是通過NonConfigurationInstances實(shí)現(xiàn)的。
ActivityThread 里面performLaunchActivity方法里面塘匣,啟動Activity 調(diào)用了Activity的attach方法脓豪,在這個方法,將已有的NonConfigurationInstances賦值給了新的Activity對象忌卤。所以Activity 獲取到的ViewMode是同一個扫夜,
這樣NonConfigurationInstances能保證ViewModelStore在Activity重建前后是同一個對象,同時也知道為啥ViewModel的生命周期比Activity的生命周期要長一點(diǎn)
LiveData 原理驰徊,如何做到生命周期感知:
涉及到LifecycleOwner屬于另一個架構(gòu)組件 lifecycle笤闯,lifecycle原理上面已經(jīng)講述
偽代碼
//LiveData數(shù)據(jù)可以再通過observe方法進(jìn)行數(shù)據(jù)回調(diào)的返回,如上代碼中的onChanged回調(diào)棍厂。
// 從Livedata添加觀察者的方法 observe 開始:
viewMode.getUsers().observe(this, new Observer<String>() {
@Override
public void onChanged(String users) {
viewmode_text.setText("viewMode獲取到的數(shù)據(jù)--" + users);
}
});
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
第一個參數(shù)為LifecycleOwner用于提供當(dāng)前的生命周期狀態(tài)颗味,DESTROYED的時候不做任何操作。
第二個為觀察者observer牺弹,首先把observer包裝成了LifecycleBoundObserver,然后把LifecycleBoundObserver維護(hù)到mObservers里
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
mObservers是一個LinkedList結(jié)構(gòu)的容器 通過putIfAbsent方法判斷浦马,容器中此觀察者是不是已經(jīng)存在,如果存在且LifecycleOwner不同的話則拋異常张漂,LifecycleOwner相同則 return 不重復(fù)添加晶默。
LifecycleBoundObserver實(shí)現(xiàn)了LifecycleObserver,為lifecycle 的觀察者航攒,通過上文的 observe方法添加到了lifecycle觀察中磺陡,
接下來主要看LifecycleBoundObserver
通過此類持有 Livedata 的觀察者observer,當(dāng) 生命周期發(fā)生變化時 會回調(diào)onStateChanged方法漠畜,然后 Livedata 的觀察者在onStateChanged中執(zhí)行相應(yīng)的邏輯。
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
//接著執(zhí)行activeStateChanged
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
通過巧妙的設(shè)計(jì)實(shí)現(xiàn)了:
1盆驹、狀態(tài)沒有變化圆丹,什么也不做。
2躯喇、變?yōu)榛睿╝ctive)就是調(diào)用onActive()辫封,非活(inactive)就調(diào)用onInactive().
3、另外廉丽,變?yōu)榛畹脑捑驼{(diào)用dispatchingValue方法倦微,此方法為回調(diào)觀察者的方法
事件的通知
LiveData通過 setValue 或 postValue 方法去改變持有的數(shù)據(jù),并通知觀察者正压,最終都是調(diào)用dispatchingValue()方法:
void dispatchingValue(@Nullable ObserverWrapper initiator) {
........................................
//遍歷之前注冊的觀察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
................................
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//開始通知了
observer.mObserver.onChanged((T) mData);
}