rxjava學(xué)習(xí)筆記

之前看了一篇響應(yīng)式編程的文章,準(zhǔn)備應(yīng)用到項(xiàng)目中,所以學(xué)習(xí)下rxjava的使用方式

官方文檔

響應(yīng)式編程

rxjava的相關(guān)博客 拉丁吳 扔物線 木水川的博客

以下代碼來自github拉丁吳的demo

1.創(chuàng)建一個(gè)被觀察者(三種方式)

create七兜、from、just

create

//創(chuàng)建被觀察者卿啡,這是最正常的創(chuàng)建方法
        Observable observable=Observable.create(new Observable.OnSubscribe<String>(){

            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("一二三四五");
                subscriber.onNext("上山打老虎");
                subscriber.onNext("老虎一發(fā)威");
                subscriber.onNext("武松就發(fā)怵");
                subscriber.onCompleted();

            }
        });

create方法接收的是一個(gè)OnSubscribe對(duì)象

public static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

from

String [] kk={"一二三四五","上山打老虎","老虎一發(fā)威","武松就發(fā)怵"};
        Observable observable=Observable.from(kk);

from接收的是一個(gè)數(shù)組

public static <T> Observable<T> from(T[] array) {
        int n = array.length;
        if (n == 0) {
            return empty();
        } else
        if (n == 1) {
            return just(array[0]);
        }
        return create(new OnSubscribeFromArray<T>(array));
    }

just

 Observable observable=Observable.just("一二三四五","上山打老虎","老虎一發(fā)威","武松就發(fā)怵");

just方法在Observable類里面有10個(gè)重載方法分別對(duì)應(yīng)10個(gè)參數(shù)

public static <T> Observable<T> just(final T value) {
        return ScalarSynchronousObservable.create(value);
    }

.
.
.

 public static <T> Observable<T> just(T t1, T t2) {
        return from((T[])new Object[] { t1, t2 });
    }

.
.
.

public static <T> Observable<T> just(T t1, T t2, T t3, T t4, T t5, T t6, T t7, T t8, T t9, T t10) {
        return from((T[])new Object[] { t1, t2, t3, t4, t5, t6, t7, t8, t9, t10 });
    }

2.創(chuàng)建一個(gè)觀察者

兩種方式

第一種

觀察者的基類是Observer

 //創(chuàng)建觀察者
        Subscriber subscriber=new Subscriber<String>() {
            @Override
            public void onCompleted() {
               
            }

            @Override
            public void onError(Throwable e) {

            }
            @Override
            public void onNext(String s) {
               
            }

        };

public abstract class Subscriber<T> implements Observer<T>, Subscription {}

第二種

通過Action
Action總共有10種(Action0 Action1.......Action9)嘱支,它們都繼承了Action
Action其實(shí)和Observer是沒有任何關(guān)系的,Action并不是Observer的子類厕九,但是它可以充當(dāng)觀察者使用蓖捶,專門處理onNext事件

public interface Action extends Function {

}
public interface Function {

}

public interface Action0 extends Action {
    void call();
}

.
.
.

public interface Action1<T> extends Action {
    void call(T var1);
}
public interface Action9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends Action {
    void call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9);
}

它們的區(qū)別只是call方法中參數(shù)的個(gè)數(shù)不同

訂閱

觀察者與被觀察者是通過訂閱來聯(lián)系起來的
被觀察者.subscribe(觀察者)
之所以這么設(shè)計(jì),是為了保證流式API調(diào)用風(fēng)格扁远,參考

訂閱流程

observable.subscribe(subscriber);
之后做了哪些事情呢俊鱼?
在Observable類里面

public final Subscription subscribe(Subscriber<? super T> subscriber) {
        return Observable.subscribe(subscriber, this);
    }

接著調(diào)用了
//subscriber是我們的觀察者,在訂閱的時(shí)候傳進(jìn)來的參數(shù)刻像,而observable代表this,就是訂閱的時(shí)候所調(diào)用的方法的對(duì)象并闲,就是我們的被觀察者

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
  //省略代碼
  // new Subscriber so onStart it
        subscriber.onStart();
//省略
       try {
            // allow the hook to intercept and/or decorate
  
//這兒調(diào)用了call方法
          RxJavaHooks.onObservableStart(observable,observable.onSubscribe).call(subscriber);
            return RxJavaHooks.onObservableReturn(subscriber);
        } catch (Throwable e) {
}


}

RxJavaHooks類中

 public static <T> Observable.OnSubscribe<T> onObservableStart(Observable<T> instance, Observable.OnSubscribe<T> onSubscribe) {
        Func2<Observable, Observable.OnSubscribe, Observable.OnSubscribe> f = onObservableStart;
        if (f != null) {
            return f.call(instance, onSubscribe);
        }
        return onSubscribe;
    }

傳進(jìn)來的參數(shù)是observable和observable的唯一屬性onSubscribe(也是構(gòu)造Observable的時(shí)候所必須的细睡,只有這個(gè)一帶參數(shù)的構(gòu)造函數(shù)),onObservableStart是不為null的,在靜態(tài)代碼塊中就已經(jīng)初始化了帝火。

/** Initialize with the default delegation to the original RxJavaPlugins. */
    static {
        init();
    }

    /** Utility class. */
    private RxJavaHooks() {
        throw new IllegalStateException("No instances!");
    }


    /**
     * Initialize the hooks via delegating to RxJavaPlugins.
     */
    @SuppressWarnings({ "rawtypes", "unchecked", "deprecation"})
    static void init() {
        onError = new Action1<Throwable>() {
            @Override
            public void call(Throwable e) {
                RxJavaPlugins.getInstance().getErrorHandler().handleError(e);
            }
        };

        onObservableStart = new Func2<Observable, Observable.OnSubscribe, Observable.OnSubscribe>() {
            @Override
            public Observable.OnSubscribe call(Observable t1, Observable.OnSubscribe t2) {
                return RxJavaPlugins.getInstance().getObservableExecutionHook().onSubscribeStart(t1, t2);
            }
        };
}
 @Deprecated
    public <T> OnSubscribe<T> onSubscribeStart(Observable<? extends T> observableInstance, final OnSubscribe<T> onSubscribe) {
        // pass through by default
        return onSubscribe;
    }

默認(rèn)返回的就是傳進(jìn)來的onSubscribe對(duì)象
所以
RxJavaHooks.onObservableStart(observable,observable.onSubscribe).call(subscriber);
其實(shí)調(diào)用的就是observable.onSubscribe的call方法溜徙,而這個(gè)onSubscribe是在構(gòu)造被觀察者的時(shí)候創(chuàng)建的
這就是從訂閱動(dòng)作發(fā)生到被觀察者中的call方法調(diào)用的流程
call方法中的參數(shù)subscriber正是我們的觀察者。

操作符

以map操作符為例

 Observable.just("picurl")
                //使用map操作來完成類型轉(zhuǎn)換
                .map(new Func1<String, Bitmap>() {
                    @Override
                    public Bitmap call(String s) {
                        //顯然自定義的createBitmapFromPath(s)方法购公,是一個(gè)極其耗時(shí)的操作
                        return createBitmapFromPath(s);
                    }
                })
                .subscribe(
                        //創(chuàng)建觀察者萌京,作為事件傳遞的終點(diǎn)處理事件
                        new Subscriber<Bitmap>() {
                            @Override
                            public void onCompleted() {
                            }

                            @Override
                            public void onError(Throwable e) {
                                //出現(xiàn)錯(cuò)誤會(huì)調(diào)用這個(gè)方法
                            }

                            @Override
                            public void onNext(Bitmap s) {
                                //處理事件
                            }
                        }
                );

map是如何對(duì)事件進(jìn)行變換處理,最后傳遞到觀察者手中的呢宏浩?

 public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return create(new OnSubscribeMap<T, R>(this, func));
    }

 public static <T> Observable<T> create(OnSubscribe<T> f) {
        return new Observable<T>(RxJavaHooks.onCreate(f));
    }

構(gòu)造一個(gè)Observable被觀察者知残,有三種方式,用create時(shí)比庄,傳入的參數(shù)是Observable.OnSubscribe,所以O(shè)nSubscripbeMap是Onsubscribe的子類,所以肯定會(huì)實(shí)現(xiàn)call方法

public final class OnSubscribeMap<T, R> implements OnSubscribe<R> {
}

public interface OnSubscribe<T> extends Action1<Subscriber<? super T>> {
        // cover for generics insanity
    }

public interface Action1<T> extends Action {
    void call(T t);
}

在OnSubscribeMap的call方法中,創(chuàng)建了一個(gè)觀察者的代理對(duì)象MapSubscriber

 @Override
    public void call(final Subscriber<? super R> o) {
        MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
        o.add(parent);
        source.unsafeSubscribe(parent);
    }


 public OnSubscribeMap(Observable<T> source, Func1<? super T, ? extends R> transformer) {
        this.source = source;
        this.transformer = transformer;
    }

這個(gè)source是我們的原始的被觀察者
source.unsafeSubscribe(parent);
所以原始的被觀察者在這里會(huì)注冊(cè)代理觀察者

以onNext方法為例

@Override
        public void onNext(T t) {
            R result;

            try {
                result = mapper.call(t);
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                unsubscribe();
                onError(OnErrorThrowable.addValueAsLastCause(ex, t));
                return;
            }

            actual.onNext(result);
        }


 public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
            this.actual = actual;
            this.mapper = mapper;
        }

mapper 是什么求妹?



public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
            this.actual = actual;
            this.mapper = mapper;
        }

MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);

public OnSubscribeMap(Observable<T> source, Func1<? super T, ? extends R> transformer) {
        this.source = source;
        this.transformer = transformer;
    }

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return create(new OnSubscribeMap<T, R>(this, func));
    }

所以mapper就是調(diào)用map方法時(shí)傳入的參數(shù)

@Override
        public void onNext(T t) {
            R result;

            try {
                result = mapper.call(t);
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                unsubscribe();
                onError(OnErrorThrowable.addValueAsLastCause(ex, t));
                return;
            }

            actual.onNext(result);
        }

調(diào)用result = mapper.call(t);就是

new Func1<String, Bitmap>() {
                    @Override
                    public Bitmap call(String s) {
                        //顯然自定義的createBitmapFromPath(s)方法,是一個(gè)極其耗時(shí)的操作
                        return createBitmapFromPath(s);
                    }
                }

然后再執(zhí)行 actual.onNext(result);actual是我們最原始的觀察者佳窑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末制恍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子神凑,更是在濱河造成了極大的恐慌净神,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溉委,死亡現(xiàn)場(chǎng)離奇詭異鹃唯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓣喊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門坡慌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人藻三,你說我怎么就攤上這事洪橘。” “怎么了棵帽?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵熄求,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我岖寞,道長(zhǎng)抡四,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮指巡,結(jié)果婚禮上淑履,老公的妹妹穿的比我還像新娘。我一直安慰自己藻雪,他們只是感情好秘噪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勉耀,像睡著了一般指煎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上便斥,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天至壤,我揣著相機(jī)與錄音,去河邊找鬼枢纠。 笑死像街,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晋渺。 我是一名探鬼主播镰绎,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼木西!你這毒婦竟也來了畴栖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤八千,失蹤者是張志新(化名)和其女友劉穎吗讶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋捆,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡关翎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸠信。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡论寨,死狀恐怖星立,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情葬凳,我是刑警寧澤绰垂,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站火焰,受9級(jí)特大地震影響劲装,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一占业、第九天 我趴在偏房一處隱蔽的房頂上張望绒怨。 院中可真熱鬧,春花似錦谦疾、人聲如沸南蹂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽六剥。三九已至,卻和暖如春峰伙,著一層夾襖步出監(jiān)牢的瞬間疗疟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工瞳氓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留策彤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓顿膨,卻偏偏與公主長(zhǎng)得像锅锨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恋沃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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

  • 本文僅為學(xué)習(xí)筆記必搞;不是原創(chuàng)文章; 給 Android 開發(fā)者的 RxJava 詳解 一:基本介紹 概念: 是一個(gè)實(shí)...
    shuixingge閱讀 664評(píng)論 0 1
  • 寫在前面的話 看了源碼也不少囊咏,但是每次看源碼都僅僅恕洲,也就是僅僅跟著作者一步步跟進(jìn)ta的方法,點(diǎn)進(jìn)去梅割,再點(diǎn)進(jìn)去霜第,再再...
    cgzysan閱讀 419評(píng)論 0 3
  • 在正文開始之前的最后,放上GitHub鏈接和引入依賴的gradle代碼: Github: https://gith...
    蘇蘇說zz閱讀 677評(píng)論 0 2
  • 正文如題,謝謝底燎。
    Winhalls_Lau閱讀 799評(píng)論 19 2
  • 互聯(lián)網(wǎng)時(shí)代双仍,當(dāng)遇到不懂的問題時(shí)枢希,許多人都習(xí)慣上網(wǎng)請(qǐng)教別人,而網(wǎng)絡(luò)上朱沃,也有不少人貢獻(xiàn)他們的答案與經(jīng)驗(yàn)苞轿。 有時(shí)候茅诱,靈活...
    c538e7746a0a閱讀 436評(píng)論 0 1