一、什么是Jetpack?
Jetpack并不是一個框架或者組件,它是一套庫辜梳、工具和指南的集合,可幫助開發(fā)者更輕松地編寫優(yōu)質(zhì)應(yīng)用泳叠。這些組件可幫助開發(fā)者遵循最佳做法作瞄、擺脫編寫樣板代碼的工作并簡化復(fù)雜任務(wù),以便將精力集中放在所需的代碼上危纫。
Android Jetpack中的很多組件并不都是新開發(fā)的宗挥,而是很早就有了,比如在Goole I/O 2017大會時推出了 Android Architecture Component(AAC)种蝶,它包括了LifeCycle契耿、LiveData、ViewModel蛤吓、Room宵喂。在Goole I/O 2018大會上,
用AndroidX替代了Android Support Library会傲,并在Android Architecture Component的基礎(chǔ)上發(fā)布了Android Jetpack锅棕,AndroidX也是屬于Android Jetpack拙泽。
Jetpack主要特性有以下三點:
1.加速開發(fā)
組件可單獨使用,也可以協(xié)同工作裸燎,當(dāng)使用kotlin語言特性時顾瞻,可以提高效率。
2.消除樣板代碼
Android Jetpack可管理繁瑣的Activity(如后臺任務(wù)德绿、導(dǎo)航和生命周期管理)荷荤。
3.構(gòu)建高質(zhì)量的強大應(yīng)用
Android Jetpack組件圍繞現(xiàn)代化設(shè)計實踐構(gòu)建而成,具有向后兼容性移稳,可以減少崩潰和內(nèi)存泄漏蕴纳。
二、Android Jetpack架構(gòu)組件 Lifecycle
2.1 什么是Lifecycle
Lifecycle用于幫助開發(fā)者管理Activity和Fragment 的生命周期
2.2 Lifecycle基本用法
先不談Activity和Fragment中如何使用个粱,先舉一個Lifecycle的簡單例子古毛。
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());//1
復(fù)制代碼新建一個MyObserver類,它實現(xiàn)了LifecycleObserver接口都许,說明MyObserver成為了一個Lifecycle的觀察者稻薇。
然后在注釋1處將MyObserver添加到LifecycleOwner中。LifecycleOwner是一個接口胶征,其內(nèi)部只有一個方法getLifecycle()塞椎,getLifecycle方法用于獲取Lifecycle,這樣就可以將MyObserver添加到Lifecycle中睛低,當(dāng)Lifecycle的生命周期發(fā)生變化時案狠,MyObserver就會觀察到,或者說是感知到钱雷。
如果使用是Java8 ,那么可以使用DefaultLifecycleObserver來替代LifecycleObserver:
class MyObserver implements DefaultLifecycleObserver {
@Override
public void onCreate(LifecycleOwner owner) {
...
}
}
復(fù)制代碼除此之外莺戒,不要忘了在build.gradle添加 "androidx.lifecycle:common-java8:<version>"
2.3.Lifecycle應(yīng)用舉例
應(yīng)用舉例準備兩個示例,在Activity中使用
package com.example.lifecycledemo1;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new MyObserver());//1
}
public class MyObserver implements LifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume(){
Log.d(TAG, "Lifecycle call onResume");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause(){
Log.d(TAG, "Lifecycle call onPause");
}
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
}
復(fù)制代碼先實現(xiàn)MyObserver急波,對ON_CREATE和ON_RESUME事件進行監(jiān)聽从铲。因為在Android Support Library 26.1.0 及其之后的版本,Activity和Fragment已經(jīng)默認實現(xiàn)了LifecycleOwner接口澄暮,所以在注釋1處可以直接使用getLifecycle方法獲取Lifecycle對象名段,這樣MyObserver就可以觀察MainActivity的生命周期變化了,LifecycleOwner可以理解為被觀察者泣懊,MainActivity默認實現(xiàn)了LifecycleOwner接口伸辟,也就是說MainActivity是被觀察者。
運行程序馍刮,打印的log如下所示信夫。
D/MainActivity: onResume
D/MainActivity: Lifecycle call onResume
D/MainActivity: Lifecycle call onPause
D/MainActivity: onPause
只要在MainActivity的onCreate方法中添加MyObserver,那么MyObserver就可以觀察到MainActivity的各個生命周期的變化。
三静稻、Android Jetpack架構(gòu)組件 LiveData
3.1 什么是LiveData
LiveData是一個感知數(shù)據(jù)變化的持有者警没,一般是感知Viewmodel的數(shù)據(jù)!
LiveData如同它的名字一樣振湾,是一個可觀察的數(shù)據(jù)持有者杀迹,和常規(guī)的observable不同,LiveData是具有生命周期感知的押搪,這意味著它能夠在Activity树酪、Fragment、Service中正確的處理生命周期大州。
LiveData的數(shù)據(jù)源一般是ViewModel续语,也可以是其它可以更新LiveData的組件。當(dāng)數(shù)據(jù)更新后厦画,LiveData 就會通知它的所有觀察者绵载,比如Activiy。與RxJava的方法不同的是苛白,LiveData并不是通知所有觀察者,它 只會通知處于Active狀態(tài)的觀察者焚虱,如果一個觀察者處于Paused或Destroyed狀態(tài)购裙,它將不會收到通知。
這對于Activiy和Service特別有用鹃栽,因為它們可以安全地觀察LiveData對象而不用擔(dān)心內(nèi)存泄漏的問題躏率。開發(fā)者也不需要在onPause或onDestroy方法中解除對LiveData的訂閱。還有一點需要注意的是一旦觀察者重新恢復(fù)Resumed狀態(tài)民鼓,它將會重新收到LiveData的最新數(shù)據(jù)薇芝。
3.2 LiveData的基本用法
LiveData是一個抽象類,它的最簡單的實現(xiàn)類為MutableLiveData丰嘉,這里舉個最簡單的例子夯到。
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
//觀察者,觀察到數(shù)據(jù)變化顯示出來
mutableLiveData.observe(this, new Observer<String>() {//1
@Override
public void onChanged(@Nullable final String s) {
Log.d(TAG, "onChanged:"+s);
}
});
//被觀察者數(shù)據(jù)饮亏,異步線程運行
mutableLiveData.postValue("Android進階三部曲");//2
}
}
注釋1處的observe方法有兩個參數(shù)分別是LifecycleOwner和 Observer<T> 耍贾,第一個參數(shù)就是MainActivity本身,第二個參數(shù)新建了一個Observer<String>路幸,在onChanged方法中得到回調(diào)荐开。注釋處的postValue方法會在主線程中更新數(shù)據(jù),這樣就會得到打印的結(jié)果简肴。
D/MainActivity: onChanged:Android進階三部曲
在大多數(shù)情況下晃听,LiveData的observe方法會放在onCreate方法中,如果放在onResume方法中,會出現(xiàn)多次調(diào)用的問題能扒。除了MutableLiveData的postValue方法佣渴,還可以使用setValue方法,它們之前的區(qū)別是赫粥,setValue方法必須在主線程使用观话,如果是在工作線程中更新LiveData,則可以使用postValue方法越平。
3.3 LiveData源碼分析
model.getLiveData().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
//響應(yīng)接受的消息
tvReceiveData.setText(newName);
}
});
1.這個代碼必須放到主線程频蛔,不然崩潰assertMainThread("observe");
2.Activity生命周期銷毀了的話直接退出不執(zhí)行,所以不會引發(fā)內(nèi)存泄漏
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
3.LifecycleBoundObserver裝飾器秦叛,封裝LifecycleOwner晦溪,Observer這兩個對象
4.owner.getLifecycle().addObserver(wrapper);將觀察者與LifecycleOwner進行綁定
5.Activity銷毀就取消訂閱,因此不會內(nèi)存泄漏
============================================================================
model.getLiveData().setValue("我是點擊按鈕發(fā)送的消息");
1.for循環(huán)遍歷所有的觀察者
2.調(diào)用觀察者的observer.mObserver.onChanged((T) mData);因此在每個觀察者的onChanged方法可以監(jiān)聽到數(shù)據(jù)變化挣跋。
總結(jié):
1.LiveData 是如何跟 LifecycleOwner 進行綁定三圆,做到感知生命周期的?
答:LifeData 在 observe 方法中用 LifecycleBoundObserver 包裝了 observer 避咆,并且通過它綁定了owner舟肉。
2.LiveData 會自動在 DESTROY 的狀態(tài)下取消訂閱,是怎么處理的查库?
答:LifecycleBoundObserver 在 onStateChanged() 方法里處理了生命周期改變的事件路媚,當(dāng)接收到 DESTROYED 的事件會自動解除跟 owner 的綁定。
生命周期變化后數(shù)據(jù)處理流程是怎么樣的樊销?
LiveData 的實現(xiàn)基于觀察者模式整慎;
LiveData 跟 LifecycleOwner 綁定,能感知生命周期變化围苫,并且只會在 LifecycleOwner 處于 Active 狀態(tài)(STARTED/RESUMED)下通知數(shù)據(jù)改變裤园;如果數(shù)據(jù)改變發(fā)生在非 active 狀態(tài),數(shù)據(jù)會變化剂府,但是不發(fā)送通知拧揽,等 owner 回到 active 的狀態(tài)下,再發(fā)送通知腺占;
LiveData 會自動在 DESTROYED 的狀態(tài)下移除 Observer 强法,取消訂閱,所以不用擔(dān)心內(nèi)存泄露湾笛;
在 LifecycleOwner 處于 DESTROYED 的狀態(tài)下饮怯,不能訂閱;
postValue 方法其實最后調(diào)用了 setValue 只不過把操作放到主線程嚎研,適合在異步線程里調(diào)用蓖墅,setValue 必須在主線程里調(diào)用库倘;
如果同時多次調(diào)用 postValue 或 setValue 修改數(shù)據(jù),只會修改成最新的那個數(shù)據(jù)论矾,也即只會收到一次通知(set post混合調(diào)用則不一定)教翩;
如果 LiveData 有數(shù)據(jù),并且 owner 在 active 狀態(tài)下贪壳,那么在訂閱的時候饱亿,會立馬收到一次通知;
一個 Observer 實例闰靴,只能綁定一個 LifecycleOwner彪笼,而一個 owner 可以綁定多個 Observer 實例;
LiveData 利用版本管理蚂且、綁定 Lifecycle 確保了只會發(fā)送最新的數(shù)據(jù)給 active 狀態(tài)下的 Observer配猫;
LiveData 基于觀察者模式,并且可以感知生命周期杏死,這使得我們使用 LiveData 既可以享受觀察者模式帶來的隔離數(shù)據(jù)與 UI 等強大的解耦能力泵肄,還可以享受感知生命周期帶來的巨大便利。并且還無需擔(dān)心內(nèi)存泄露這個令人頭疼的問題淑翼。
四腐巢、Android Jetpack架構(gòu)組件 ViewModel
4.1.什么是ViewModel
ViewModel,感知生命周期的形式來存儲和管理視圖相關(guān)的數(shù)據(jù)玄括。針對數(shù)據(jù)冯丙。
在說ViewModel前,我們需要解一下MVVM和DataBinding.MVVM最早于2005年被微軟的架構(gòu)師John Gossman提出惠豺,在2015年Google I/O大會上發(fā)布了MVVM的支持庫DataBinding,DataBinding遭到了一些開發(fā)者的詬病风宁,主要是綁定數(shù)據(jù)時如果出現(xiàn)問題會很難排查洁墙,這樣就沒有一個合適的ViewModel規(guī)范來幫助開發(fā)者來實現(xiàn)MVVM。
在2017年的Google I/O大會上戒财,谷歌推出了ViewModel組件热监,來規(guī)范化ViewModel層。
ViewModel顧名思義饮寞,是以感知生命周期的形式來存儲和管理視圖相關(guān)的數(shù)據(jù)孝扛。ViewModel主要有以下的特點:
1.當(dāng)Activity被銷毀時,我們可以使用onSaveInstanceState()方法恢復(fù)其數(shù)據(jù)幽崩,這種方法僅適用于恢復(fù)少量的支持序列化苦始、反序列化的數(shù)據(jù),不適用于大量數(shù)據(jù)慌申,如用戶列表或位圖陌选。而ViewModel不僅支持大量數(shù)據(jù),還不需要序列化、反序列化操作咨油。
2.Activity/Fragment(視圖控制器)主要用于顯示視圖數(shù)據(jù)您炉,如果它們也負責(zé)數(shù)據(jù)庫或者網(wǎng)絡(luò)加載數(shù)據(jù)等操作,那么一旦邏輯過多役电,會導(dǎo)致視圖控制器臃腫赚爵,ViewModel可以更容易,更有效的將視圖數(shù)據(jù)相關(guān)邏輯和視圖控制器分離開來法瑟。
3.視圖控制器經(jīng)常需要一些時間才可能返回的異步調(diào)用冀膝,視圖控制器需要管理這些調(diào)用,在合適的時候清理它們瓢谢,以確保它們的生命周期不會大于自身畸写,避免內(nèi)存泄漏。而ViewModel恰恰可以避免內(nèi)存泄漏的發(fā)生氓扛。
4.2.ViewModel基本使用
自定義ViewModel繼承ViewMode枯芬,實現(xiàn)自定義ViewModel。
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
private MutableLiveData<String> name;
public LiveData<String> getName() {
if (name == null) {
name = new MutableLiveData<String>();
addName();
}
return name;
}
private void addName() {
name.setValue("Android進階解密");
}
}
getName方法中創(chuàng)建一個MutableLiveData采郎,并通過MutableLiveData的setValue方法來更新數(shù)據(jù)千所。
使用ViewModel然后就可以在Activity中使用MyViewModel了,如下所示蒜埋。
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getName().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.d(TAG, "暢銷書:"+s);
}
});
}
}
通過ViewModelProviders就可以獲得MyViewModel的實例淫痰,然后配合LiveData就可以觀察Name的變化。打印結(jié)果為:
D/MainActivity: 書名為Android進階解密
4.3.ViewModel的生命周期
在旋轉(zhuǎn)設(shè)備屏幕時整份,Activity會被銷毀重新創(chuàng)建待错,而ViewModel卻不會這樣,它的生命周期如下所示烈评。
可以看到火俄,Activity的生命周期不斷變化,經(jīng)歷了被銷毀重新創(chuàng)建讲冠,而ViewModel的生命周期沒有發(fā)生變化瓜客。
4.4 ViewModel源碼解析
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
1.ViewModel是怎么創(chuàng)建的?
get方法里面反射實例化ViewModel
2.ViewModel是怎么存儲的竿开?
ViewModelStore mViewModelStore;
ViewModelStore 結(jié)構(gòu):HashMap<String, ViewModel>
mViewModelStore.put(key, viewModel);
3.ViewModel為什么可以實現(xiàn)屏幕旋轉(zhuǎn)不丟失數(shù)據(jù)谱仪? 屏幕狀態(tài)發(fā)生改變會拿到上一次屏幕旋轉(zhuǎn)的值
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
ViewModelStore mViewModelStore = nc.viewModelStore;
每次拿到上次屏幕旋轉(zhuǎn)的ViewModelStore ,從而拿到ViewModel
參考資料:
Android Jetpack架構(gòu)組件(一)帶你了解Android Jetpack
https://juejin.cn/post/6844903976815558663
Android Jetpack架構(gòu)組件(二)一文帶你了解Lifecycle(使用篇)
https://juejin.cn/post/6844903977788801032
Android Jetpack架構(gòu)組件(三)一文帶你了解Lifecycle(原理篇)
https://juejin.cn/post/6844903977788817416
Android Jetpack架構(gòu)組件(四)一文帶你了解LiveData(使用篇)
https://juejin.cn/post/6844903982691794957
Android Jetpack架構(gòu)組件(五)一文帶你了解LiveData(原理篇)
https://juejin.cn/post/6844903982691794952
Android Jetpack架構(gòu)組件(六)一文帶你了解ViewModel的使用和原理
https://juejin.cn/post/6844903983471935495