Android Jetpack架構(gòu)組件之Lifecycle入門

態(tài)度決定一切 細節(jié)決定成敗

一、前言

——回顧了一下之前學(xué)習(xí)過的東西并打算把這些東西整理成文章,加深映像和理解,同時也傳達自己的見解供大家參考,若存在錯誤或不足的地方,希望您能指出。
本篇主要介紹Lifecycle,根據(jù)下面結(jié)構(gòu)圖進行分析。

本篇結(jié)構(gòu)圖

LifeCycle相關(guān)鏈接——官方文檔接口文檔相關(guān)依賴文檔

二、簡介

(1)是什么

—— Lifecycle 是具有生命周期感知能力的組件。簡單的理解當(dāng)Activity/Fragment的生命周期產(chǎn)生變化時,lifeCycle組件也會有相應(yīng)的生命周期變化。我們可以通過使用lifeCycle組件在自定義的類中管理Activity/fragment的生命周期。
主要由三大部分構(gòu)成:Lifecycle、LifecycleOwner、LifecycleObserver

  • Lifecycle:是一個持有組件生命周期狀態(tài)與事件(如Activity或Fragment)的信息的類
  • LifecycleOwner:Lifecycle的提供者,通過實現(xiàn)LifecycleOwner接口來訪問Lifecycle(生命周期)對象。Fragment和FragmentActivity類實現(xiàn)了LifecycleOwner接口,它具有訪問生命周期的getLifecycle方法。您還可以在自己的類中實現(xiàn)LifecycleOwner。
  • LifecycleObserver:Lifecycle觀察者,實現(xiàn)該接口的類,通過注解的方式,可以通過被LifecycleOwner類的addObserver(LifecycleObserver o)方法注冊,被注冊后,LifecycleObserver便可以觀察到LifecycleOwner的生命周期事件。

(2)有什么用

—— 常見的模式是在Activity和Fragment的生命周期方法中實現(xiàn)依賴組件的操作(取消注冊/監(jiān)聽,釋放內(nèi)存...),如果不這樣做可能會觸發(fā)內(nèi)存泄漏甚至應(yīng)用程序崩潰。然而,這種模式會導(dǎo)致糟糕的代碼組織和錯誤的擴散,。通過使用生命周期感知組件,您可以將依賴組件的代碼移出生命周期方法,并移到組件本身

這里舉個官方文檔的例子說明一下,也更容易理解
常見的模式

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
    }
}

實際的運用中,Activity的onStart()和onStop()方法中會有很多的調(diào)用來管理UI和其他組件,以響應(yīng)生命周期的當(dāng)前狀態(tài)。管理多個組件會在生命周期方法中放置大量的代碼,這使得它們很難維護。

Lifecycle模式

public class MyLocationListener implements LifecycleObserver {
    private static final String TAG = "MyLocationListener ";
    public MyLocationListener(Context context, Callback callback) { /*...*/ }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void start(){
        Log.e(TAG, "start: " );
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stop(){
        Log.e(TAG, "stop: " );
    }
}
//Activity/Fragment中使用
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLocationListener myLocationListener = new MyLocationListener(this, (location) -> { /* update UI */ });
    getLifecycle().addObserver(myLocationListener );
}

通過Lifecycle組件可以在各自的類中通過注釋響應(yīng)生命周期的當(dāng)前狀態(tài)。

(3)有什么優(yōu)點

1.結(jié)構(gòu)更加清晰,更容易管理生命周期
2.降低維護難度
3.降低耦合度

就是如此簡單而又好用,那么具體如何使用請看下文分解。

三、基本使用

(4)怎么使用

  • 添加依賴

implementation 'androidx.appcompat:appcompat:1.1.0'

// 可選
dependencies {
    def lifecycle_version = "2.1.0"
    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}
  • 定義觀察者
// 定義一個類實現(xiàn)LifecycleObserver接口,通過向其方法添加注釋來監(jiān)視組件的生命周期狀態(tài)
public class MyObserver implements LifecycleObserver {
    private static final String TAG = "MyObserver";
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void start(){
        Log.e(TAG, "start: " );
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stop(){
        Log.e(TAG, "stop: " );
    }
}
  • 添加觀察者
//通過調(diào)用生命周期類的addObserver()方法并傳遞觀察者的實例來添加觀察者。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyObserver myObserver = new MyObserver();
    getLifecycle().addObserver(myObserver);
}

這里提供入門級使用方式,下面舉個例子

  • 案例
    ——廣播的注冊與取消注冊處理

1.定義廣播接收者

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("onReceive: action ",intent.getAction());
        Log.e("onReceive: content ",intent.getStringExtra("content"));
    }
}

2.定義lifecycle觀察者

class BroadCastObserver implements LifecycleObserver {
    private static final String TAG = "BroadCastObserver";
    private Activity mActivity;
    private MyBroadcastReceiver mBroadcastReceiver;
    public BroadCastObserver(Activity activity) {
        this.mActivity = activity;
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void register(){
        Log.e(TAG, "register: " );
        mBroadcastReceiver = new MyBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("xxx");
        mActivity.registerReceiver(mBroadcastReceiver, intentFilter);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void unRegister(){
        Log.e(TAG, "unRegister: " );
        mActivity.unregisterReceiver(mBroadcastReceiver);
    }
}

3.添加觀察者

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BroadCastObserver mBroadCastObserver = new BroadCastObserver(this);
        getLifecycle().addObserver(mBroadCastObserver);
    }

4.發(fā)送廣播

    public void onClick(View v) {
        Intent intent = new Intent();
        intent.setAction("xxx");
        intent.putExtra("content", "廣播1號");
        sendBroadcast(intent);
    }

輸出結(jié)果

好了,使用方式就簡單介紹到這里。大家有空也可以自己試試Service

四、原理

本來想寫成一篇的,結(jié)果發(fā)現(xiàn)分析的源碼有點多,只好拆開來。避免篇幅太長,看著累。。。
《Android Jetpack架構(gòu)組件之Lifecycle源碼分析》

五、總結(jié)

也不知道要寫什么。就簡單描述一下使用過程,lifecycle使用了觀察者模式。
1.先聲明了一個觀察者,用來監(jiān)聽被觀察者(Activity/Fragment)。
2.觀察者通過實現(xiàn)LifecycleObserver接口,使用注解來監(jiān)聽被觀察者發(fā)生的變化。
3.那么是如何監(jiān)聽的,這次就使用到了lifecycle。lifecycle相當(dāng)于一個橋梁,把兩者關(guān)聯(lián)在一起。
4.被觀察者通過實現(xiàn)LifecycleOwner接口先連接了橋梁。
5.觀察者則通過getLifecycle().addObserver()方法也建立起連接。
通俗描述大概就是這么一回事,具體的實現(xiàn)方式還是要根據(jù)源碼來分析。事實并沒想的這么簡單,源碼也是挺多。

六、內(nèi)容推薦

七、項目參考

Demo例子鑲嵌到下面Demo中
Github ——apk下載體驗地址
若您發(fā)現(xiàn)文章中存在錯誤或不足的地方,希望您能指出!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內(nèi)容