Android Arch LifeCycle 用法詳解與源碼解析

一.序

自從Google IO 大會提出 Android Architecture Components武花,越來越多的使用組件加入其中。其中
Handling lifecycles with lifecycle-aware components
這篇文章就向我介紹了LifeCycle這個超實用組件望艺。

二.LifeCycle簡介

2.1為什么我們要使用LifeCycle票腰?

我們寫代碼的時候難免會寫寫一些Presenter或者M(jìn)ananger或者一些業(yè)務(wù)性很強(qiáng)的View堕油。來把很一些業(yè)務(wù)邏輯從Activity中分解掉。但是不免遇到的問題就是乐严。上述這些輔助類不像Activity和Fragment一樣擁有比較完善的生命周期瘤袖。

當(dāng)然我們我們也可以這樣寫:
public interface IPresenter {
    void onCreate();

    void onStart();

    void onResume();

    void onPause();

    void onStop();

    void onDestroy();
}
public class MainPresenter implements IPresenter {

    public MainPresenter(Context context){

    }

    @Override
    public void onCreate() {

    }

    @Override
    public void onStart() {

    }

    @Override
    public void onResume() {

    }

    @Override
    public void onPause() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void onDestroy() {

    }
}
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private IPresenter mPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        setContentView(R.layout.activity_main);
        mPresenter = new MainPresenter(this);
        mPresenter.onCreate();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart: ");
        mPresenter.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: ");
        mPresenter.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause: ");
        mPresenter.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop: ");
        mPresenter.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
        mPresenter.onDestroy();
    }
}

這個例子很簡單。我們當(dāng)然可以這么寫昂验。但是如果對于一個復(fù)雜Activity和Fragment來說捂敌。可能綁定了多個Presenter既琴,Manager占婉,或者View。那這個代碼寫起來就會很復(fù)雜甫恩。尤其是當(dāng)這些東西被其他人復(fù)用的時候逆济,很難讓別人也注意到這些細(xì)節(jié)。(就是在他們的Activity中的對應(yīng)生命周期要調(diào)用這些)

2.2 隆重推出LifeCycle

Google也發(fā)現(xiàn)了這樣的問題。所以在support包 26.1.0版本后 奖慌,android.support.v4.app中的FragmentActivityFragment中已經(jīng)集成了Lifecycle相關(guān)的功能抛虫。

簡單說一下LifeCycle的原理吧:

假定一個需要觀察生命周期的Presenter實例

  1. 首先通過Fragment或者FragmentActivitygetLifeCycle方法返回的LifecycleRegistry實例的addObserver()方法,加入到FastSafeIterableMap中简僧。
  2. 然后將Presenter的生命周期快進(jìn)到現(xiàn)在的節(jié)點(diǎn):例如現(xiàn)在LifecycleOwner的狀態(tài)是STARTED建椰。Presenter將會連續(xù)收到ON_CREATEON_START兩事件岛马。
  3. 剩下的交給LifeCycle棉姐,自此之后Presenter的生命周期將和宿主保持一致。
關(guān)鍵類介紹:
  • FastSafeIterableMap 管理觀察者的數(shù)據(jù)結(jié)構(gòu)啦逆,對于在迭代的時候進(jìn)行修改做了一些優(yōu)化伞矩。
  • LifecycleRegistry LifeCycle業(yè)務(wù)核心類,完成觀察者增減蹦浦,觀察者STATE切換等核心邏輯
  • LifecycleOwner 宿主Activity實現(xiàn)這個接口,android.support.v4.app 中的Fragment撞蜂,FragmentActivity已經(jīng)實現(xiàn)這個接口了盲镶。我們也可以給我們自己的Activity實現(xiàn)這個,詳情請看3.2章節(jié)蝌诡。
  • ClassesInfoCache 通過運(yùn)行時注解的方式找到Presenter中想觀測的生命周期溉贿。

三.簡單用法

3.1 Presenter實現(xiàn)LifecycleObserver

public class MainPresenter implements LifecycleObserver {

  public static final String TAG = "MainActivity";
  public String name;

  public MainPresenter(String name) {
    this.name = name;
  }
  //通過運(yùn)行時注解的方式實現(xiàn)生命周期,是不是很像EventBus
  @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) public void onCreate() {
    Log.d(TAG, name + "onCreate");
  }

  @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onStart() {
    Log.d(TAG, name + "onStart");
  }

  @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume() {
    Log.d(TAG, name + "onResume");
  }

  @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onPause() {
    Log.d(TAG, name + "onPause");
  }

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onStop() {
    Log.d(TAG, name + "onStop");
  }
  //比較特殊的一個回調(diào)會在任何生命周期回調(diào)的時候都回調(diào)這里
  //@OnLifecycleEvent(Lifecycle.Event.ON_ANY) public void onDestroy() {
  //  Log.d(TAG, "ON_ANY");
  //}
}

Activity只需要把實現(xiàn)了LifecycleObserverMainPresenter交給LifeCycle管理即可

public class MainActivity extends AppCompatActivity {

  public static final String TAG = "MainActivity";

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate");
    setContentView(R.layout.activity_main);
    MainPresenter mainPresenter = new MainPresenter(TAG);
    //把MainPresenter交給LifeCycle管理就OK了
    getLifecycle().addObserver(mainPresenter);
  }
  @Override protected void onStart() {
    super.onStart();
    Log.d(TAG, "onStart");
  }

  @Override protected void onRestart() {
    super.onRestart();
    Log.d(TAG, "onRestart");
  }

  @Override protected void onResume() {
    super.onResume();
    Log.d(TAG, "onResume");
  }

  @Override protected void onPause() {
    super.onPause();
    Log.d(TAG, "onPause");
  }

  @Override protected void onStop() {
    super.onStop();
    Log.d(TAG, "onStop");
  }

  @Override protected void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy");
  }
}

輸出結(jié)果如下

生命周期輸出結(jié)果

當(dāng)然值得注意的

  • 啟動階段 先回調(diào)Activity的生命周期再回調(diào)LifeCycle的生命周期
  • 結(jié)束階段 先回調(diào)LifeCycle的生命周期再回調(diào)Activity的生命周期

發(fā)揮一下想象力浦旱,只要是附著在Activity或者Fragment上的任何實例都可以采用這樣的管理方式宇色,讓其達(dá)到一個自生自滅的問題。是不是就少去了很多內(nèi)存泄漏的問題颁湖。

3.2當(dāng)然也可以這樣用

創(chuàng)建一個自定義的LifeCycle

public class MainActivity1 extends Activity implements LifecycleOwner {
 private LifecycleRegistry mLifecycleRegistry;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "Activity->onCreate");
    setContentView(R.layout.activity_main);
    mLifecycleRegistry = new LifecycleRegistry(this);
  }
 @NonNull @Override public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
  }
}
LifeCycle狀態(tài)圖

四.最佳實踐

當(dāng)然這么好用的東西已經(jīng)和Arch中的其他組件宣蠕,例如DataBinding以及ViewModel可以有一些配合。以后有機(jī)會會嘗試一下甥捺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抢蚀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子镰禾,更是在濱河造成了極大的恐慌皿曲,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吴侦,死亡現(xiàn)場離奇詭異屋休,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)备韧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門劫樟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事毅哗√拢” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵虑绵,是天一觀的道長尿瞭。 經(jīng)常有香客問我,道長翅睛,這世上最難降的妖魔是什么声搁? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮捕发,結(jié)果婚禮上疏旨,老公的妹妹穿的比我還像新娘。我一直安慰自己扎酷,他們只是感情好檐涝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著法挨,像睡著了一般谁榜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凡纳,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天窃植,我揣著相機(jī)與錄音,去河邊找鬼荐糜。 笑死巷怜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的暴氏。 我是一名探鬼主播延塑,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼答渔!你這毒婦竟也來了页畦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤研儒,失蹤者是張志新(化名)和其女友劉穎豫缨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體端朵,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡好芭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冲呢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舍败。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出邻薯,到底是詐尸還是另有隱情裙戏,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布厕诡,位于F島的核電站累榜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏灵嫌。R本人自食惡果不足惜壹罚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寿羞。 院中可真熱鬧猖凛,春花似錦、人聲如沸绪穆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玖院。三九已至菠红,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間司恳,已是汗流浹背途乃。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工绍傲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扔傅,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓烫饼,卻偏偏與公主長得像猎塞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杠纵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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