鍍金池/ 教程/ Android/ Observables and updatables
Custom observables
Compiled functions
Reactive programming
Reservoirs and parallelism
Incrementally Agerifying legacy code
Observables and updatables
Compiled repositories
Repositories

Observables and updatables

上一篇所講, 被觀察者(Observable)作為事件源,觀察者(updatable)監(jiān)聽(tīng)(觀察)事件。

注冊(cè)觀察者(Updatable)方法:Observable.addUpdatable(Updatable)

注銷(xiāo)觀察者(Updatable)方法:Observable.removeUpdatable(Updatable)

事件分發(fā)給觀察者(Updatable)方法:Updatable.update()
在activity中的用法舉例:

public class MyUpdatableActivity extends Activity implements Updatable {
  private Observable observable;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    observable = new MyObservable();
  }

  @Override
  public void update() {
    // 事件通知 處理
  }

  @Override
  protected void onResume() {
    super.onResume();
    observable.addUpdatable(this);
    update();
  }

  @Override
  protected void onPause() {
    super.onPause();
    observable.removeUpdatable(this);
  }
}

Updatable的注冊(cè)和注銷(xiāo)必須配對(duì)使用。不能重復(fù)注冊(cè)Updatable,不能注銷(xiāo)沒(méi)有注冊(cè)過(guò)的Updatable,也不能重復(fù)注銷(xiāo)Updatable,等其他非法操作。

Activation lifecycle and event chain

被觀察者(Observable)的狀態(tài):
_active_狀態(tài)(活動(dòng)狀態(tài)):有觀察者 (至少注冊(cè)一個(gè)了Updatable)
_inactive_狀態(tài)(非活動(dòng)狀態(tài)):沒(méi)有觀察者 (沒(méi)有注冊(cè)的Updatable)

也就是, 注冊(cè)Updatable讓Observable從非活動(dòng)狀態(tài)激活為活動(dòng)狀態(tài),當(dāng)Updatable全部注銷(xiāo)了,Observable從活動(dòng)狀態(tài)變?yōu)榉腔顒?dòng)狀態(tài)。

http://wiki.jikexueyuan.com/project/agera-wiki-cn/images/observablelifecycle.png" alt="" />

被觀察者(Observable)還可以觀察其它“上游”(事件傳播路徑)的被觀察者們(Observables),把它們的事件轉(zhuǎn)換成自己的事件。 一個(gè)常見(jiàn)的例子:一個(gè)數(shù)據(jù)倉(cāng)庫(kù)(Repository),它的數(shù)據(jù)依賴另一個(gè)數(shù)據(jù)倉(cāng)庫(kù)(Repository)的數(shù)據(jù)。

為了事件傳播路徑的正確性, 處于中間位置的被觀察者(Observable)一般持有上游被觀察者(Observable)的強(qiáng)引用, 通常當(dāng)自己激活的時(shí)候向上游注冊(cè)觀察者(Updatable), 當(dāng)自己非活動(dòng)的時(shí)候向上游注銷(xiāo)觀察者(Updatable)。

這就是說(shuō),在下游方向上的強(qiáng)引用只用于注冊(cè)/注銷(xiāo)觀察者(Updatable),這也意味著,在最下游的觀察者(Updatable)(那些不被中間位置的被觀察者管理的被觀察者們) 最終控制所有觀察者(Updatable)的活動(dòng)和非活動(dòng)狀態(tài)。

http://wiki.jikexueyuan.com/project/agera-wiki-cn/images/downstream.png" alt="" />

UI lifecycle

事件鏈在構(gòu)建有生命周期UI的響應(yīng)式架構(gòu)方面非常有用。UI元素比如Activity、Fragment、其中的View, Android生命周期中定義的成對(duì)狀態(tài)變化,比如:onStart 到 onStop,onResume 到 onPause,onAttachedToWindow 到 onDetachedFromWindow 等等。

讓UI元素成為或者擁有一個(gè)觀察者(Updatable),通過(guò)從數(shù)據(jù)倉(cāng)庫(kù)(Repository)獲取數(shù)據(jù)來(lái)更新UI。反過(guò)來(lái)數(shù)據(jù)倉(cāng)庫(kù)(Repository)可以使用其他的事件源和數(shù)據(jù)源(不一定是Repository)來(lái)計(jì)算自己的數(shù)據(jù)。

在UI元素生命周期的開(kāi)始,注冊(cè)觀察者(Updatable),然后數(shù)據(jù)倉(cāng)庫(kù)(Repository)處于活動(dòng)狀態(tài)。這將連接事件鏈,激活所有相關(guān)的數(shù)據(jù)處理流程,保持?jǐn)?shù)據(jù)和UI是最新的。

在UI元素生命周期結(jié)束時(shí),同一個(gè)數(shù)據(jù)倉(cāng)庫(kù)(Repository)注銷(xiāo)觀察者(Updatable),假設(shè)所有觀察者(Updatable)都被注銷(xiāo),那么事件鏈將級(jí)聯(lián)斷開(kāi)。

如果UI元素是不會(huì)再激活(例如activity.onDestroyed()),因?yàn)楫?dāng)前系統(tǒng)不活動(dòng)了沒(méi)有下游的引用,UI元素可以被垃圾回收,因此很容易預(yù)防Activity泄漏。

http://wiki.jikexueyuan.com/project/agera-wiki-cn/images/uilifecycle.png" alt="" />

Threading

Agera 推薦指明執(zhí)行線程, 使用Loopers(Looper在Android中大量存在, 比如:APP Main Looper 和 IntentService中)來(lái)定義下面的線程約定。

為了處理內(nèi)部狀態(tài)生命周期,每一個(gè)觀察者(Updatable)在生命周期內(nèi)都關(guān)聯(lián)一個(gè)有Looper的線程(worker Looper thread),有Looper的線程就是實(shí)例化被觀察者(Observable)的線程。

被觀察者(Observable)的注冊(cè)和注銷(xiāo)事件分發(fā)都是通過(guò)Looper。如果被觀察者觀察了其它被觀察者,它內(nèi)部的被觀察者(Observable)將會(huì)從當(dāng)前線程注冊(cè)到上游的觀察者(Updatable)。

被觀察者(Observable)必須在有Looper的線程上注冊(cè)觀察者(Updatable),觀察者(Updatable)和被觀察者(Observable)可以運(yùn)行在不同的線程。

被觀察者(Observable)會(huì)使用相同Looper的線程的分發(fā)Updatable.update()。

注銷(xiāo)觀察者(Updatable)可以在任何線程, 但為了避免觀察者注銷(xiāo)后,事件被分發(fā)在內(nèi)部形成競(jìng)爭(zhēng)條件, 推薦注冊(cè)和注銷(xiāo)觀察者(Updatable)在同一個(gè)線程完成。

開(kāi)發(fā)者有責(zé)任保證Looper的存活和被觀察者們(Observables)一樣。由于Looper導(dǎo)致的異常和內(nèi)存泄漏是開(kāi)發(fā)者的責(zé)任。 然而在實(shí)踐中,絕大多數(shù)情況下都是使用主線程Looper,而主線程是隨app一直存活著。

上一篇:Compiled functions下一篇:Repositories