Android開源框架集合分享-響應式函數(shù)編程Rx

? ? ? ?今天來給大家介紹當下比較流行的響應式函數(shù)編程艰管,以下是整理和搜集整理的關于Rx的一些資料彬呻。響應式函數(shù)編程

確實是一種對新入行的人來說是一種新穎而又高效的編程方式俭令。但是不建議新手采用這種方法進行立項驻粟,其中的牽扯到

觀察者模式友扰,訂閱者模式還得等看過一定的算法和設計模式之后役电,才能理解的恰如其分赚爵,使用起來也可以得心應手,不過

在學習基礎的時候法瑟,理解和練習一些小的demo冀膝,對學習設計模式還是很有幫追的。今天介紹的實際上只有只有一種霎挟,就是

RxJava與RxAndroid,當然現(xiàn)在也有很多框架窝剖,像上幾篇提高的網絡請求OkGo都支持Rx的擴展,基于此給大家分享一下酥夭。

5枯芬、響應式函數(shù)編程Rx(Reactive Extensions)

主頁:https://github.com/ReactiveX/RxJava

中文資料:(這是一些大神分享一些學習的資料,參照的學習采郎,確實英語有點尷尬了)

? ? ? ? ? ? ? https://github.com/lzyzsd/Awesome-RxJava

? ? ? ? ? ? ? https://www.zhihu.com/question/35511144

含義:

? ? ?RxJava 的異步實現(xiàn)千所,是通過一種擴展的觀察者模式來實現(xiàn)的。

? ? ?觀察者模式面向的需求是:A 對象(觀察者)對 B 對象(被觀察者)的某種變化高度敏感蒜埋,需要在 B 變化的一瞬間做出反應

用途:

? ? 異步操作

? ? 在程序邏輯異常復雜的情況下,仍然可以讓代碼的邏輯保持簡潔

配置: 添加依賴:

compile'io.reactivex.rxjava2:rxandroid:2.0.1'

compile'io.reactivex.rxjava2:rxjava:2.1.0'

如果結合Retrofit使用,需要添加以下依賴

compile 'com.squareup.retrofit2:retrofit:2.0.1'

compile 'com.squareup.retrofit2:converter-gson:2.0.1'

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'

基本的理解和用法

1.被觀察者: Observable

? ? ?作用: 決定什么時候觸發(fā)事件以及觸發(fā)怎樣的事件

創(chuàng)建方法:

? ? Observable.just(T...) 參數(shù)為單個的

? ? Observable.from(T[]) / Observable.from(Iterable)??參數(shù)為數(shù)組或Iterable

2.觀察者: Observer

? ?作用: 當事件觸發(fā)的時候將有怎樣的行為

? ?實現(xiàn)類有Observer / Subscriber

3.訂閱: subscribe

? ?作用: 把Observable和Observer關聯(lián)起來

? ?方法:

? ?observable.subscribe(observer);

? ?observable.subscribe(subscriber);

4.事件

? ?onNext():普通事件

? ?onCompleted():事件隊列完結

? onError(): 事件隊列異常

? 需要注意的是onCompleted()和onError()是互斥的.調用了其中一個就不應該觸發(fā)另一個.

5.測試程序

?? ? ?現(xiàn)有一個數(shù)組 String[] arr ={"afdsa", "bfdsa", "cfda"}, 把其中以字母"a"開頭的字符串找出來并加上"from Alpha",最后打印出新的字符串的長度

? ?private void simpleDemo() {

? ? ? String[] arr = {"afdsa", "bfdsa", "cfda"};

? ? ? Observable

? ? ? ? ? ? ? ? ? ? ? .from(arr)

? ? ? ? ? ? ? ? ? ? ? .filter(new Func1() {

? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? public Boolean call(String s) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return s.startsWith("a");

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ? ? ? ?.map(new Func1() {

? ? ? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? ? ?public String call(String s) {

? ? ? ? ? ? ? ? ? ? ? ? ? return s + " from Alpha";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ?})

? ? ? ? ? ? ? ? ? ? ?.subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? ? ?public void call(String s) {

? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("Rxjava:" + s.length());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ?});

? ? ? ? ? ? ? ? ? ?for (int i = 0; i < arr.length; i++) {

? ? ? ? ? ? ? ? ? ? ? ?String temp = arr[i];

? ? ? ? ? ? ? ? ? ? ? ?if (temp.startsWith("a")) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? temp += " from Alpha";

? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("Normal:" + temp.length());

? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? }

? ? ?由指定的一個 drawable 文件 id 取得圖片淫痰,并顯示在 ImageView 中,并在出現(xiàn)異常的時候打印 Toast 報錯

? ? ?private void simpleDemo() {

? ? ? ? ? ? ? ? ?final int drawID = R.mipmap.ic_launcher;

? ? ? ? ? ? ? ? ?Observable

? ? ? ? ? ? ? ? ?.create(new Observable.OnSubscribe() {

? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ?public void call(Subscriber subscriber) {

? ? ? ? ? ? ? ? ?Drawable drawable = getResources().getDrawable(drawID);

? ? ? ? ? ? ? ? ?subscriber.onNext(drawable);

? ? ? ? ? ? ? ? ?subscriber.onCompleted();

? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ?.subscribe(new Observer() {

? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ?public void onCompleted() {

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void onError(Throwable e) {

? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ?public void onNext(Drawable drawable) {

? ? ? ? ? ? ? ? ? ? imageView.setImageDrawable(drawable);

? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ?});

? ? ? }

6.Scheduler(調度器)

? ? 作用: 控制線程.指定某一段代碼在那個線程里運行.

? ? 在不指定線程的情況下整份, RxJava 遵循的是線程不變的原則待错,即:在哪個線程調用 subscribe(),就在哪個線程生產事件烈评;在哪個線程生產事件火俄,就在哪個線程消費事件。如果需要切換線程讲冠,就需要用到 Scheduler (調度器)瓜客。

? ?在RxJava 中,Scheduler ——調度器竿开,相當于線程控制器谱仪,RxJava 通過它來指定每一段代碼應該運行在什么樣的線程。RxJava 已經內置了幾個 Scheduler 否彩,它們已經適合大多數(shù)的使用場景:

? ?內置的Scheduler:

? ?Schedulers.immediate(): 直接在當前線程運行疯攒,相當于不指定線程。這是默認的 Scheduler列荔。

? ?Schedulers.newThread(): 總是啟用新線程敬尺,并在新線程執(zhí)行操作枚尼。

? ?Schedulers.io(): I/O 操作(讀寫文件、讀寫數(shù)據(jù)庫砂吞、網絡信息交互等)所使用的 Scheduler署恍。行為模式和 newThread() 差不多,區(qū)別在于 io() 的內部實現(xiàn)是是用一個無數(shù)量上限的線程池呜舒,可以重用空閑的線程锭汛,因此多數(shù)情況下 io() 比 newThread() 更有效率笨奠。不要把計算工作放在 io() 中袭蝗,可以避免創(chuàng)建不必要的線程。

? ?Schedulers.computation(): 計算所使用的 Scheduler般婆。這個計算指的是 CPU 密集型計算到腥,即不會被 I/O 等操作限制性能的操作,例如圖形的計算蔚袍。這個 Scheduler 使用的固定的線程池乡范,大小為 CPU 核數(shù)。不要把 I/O 操作放在 computation() 中啤咽,否則 I/O 操作的等待時間會浪費 CPU晋辆。

? ?AndroidSchedulers.mainThread(): Android專用,它指定的操作將在 Android 主線程運行。

? 指定線程的方法:

? Observable.subscribeOn():指定 subscribe() 所發(fā)生的線程宇整,即 Observable.OnSubscribe 被激活時所處的線程瓶佳。或者叫做事件產生的線程

? Observable.observeOn():指定 Subscriber 所運行在的線程鳞青“运牵或者叫做事件消費的線程。

7.數(shù)據(jù)變換

? 作用: 就是將事件序列中的對象或整個序列進行加工處理臂拓,轉換成不同的事件或事件序列

? ?Observable.map:??一對一的轉換

? private void simpleDemo() {

? ? ? Observable

? ? ? ? ? ? ? ? ? ? ? ?.just(R.mipmap.ic_launcher)

? ? ? ? ? ? ? ? ? ? ? ?.map(new Func1() {

? ? ? ? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? ? ? ?public Drawable call(Integer integer) {

? ? ? ? ? ? ? ? ? ? ? ? ? ?return getResources().getDrawable(integer);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? public void call(Drawable drawable) {

? ? ? ? ? ? ? ? ? ? ? ? ? ?imageView.setImageDrawable(drawable);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? Observable.flatMap: 一對多的轉換

? ? ? ? ? public class Course {

? ? ? ? ? ? ? ?private String name;

? ? ? ? ? ? ? ?private int id;

? ? ? ? ? ? ? ?public Course(String name, int id) {

? ? ? ? ? ? ? ? ? ?this.name = name;

? ? ? ? ? ? ? ? ? ?this.id = id;

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ?public String getName() {

? ? ? ? ? ? ? ? ? ?return name;

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ?public void setName(String name) {

? ? ? ? ? ? ? ? ? ?this.name = name;

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? public int getId() {

? ? ? ? ? ? ? ? ? return id;

? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ?public void setId(int id) {

? ? ? ? ? ? ? ? ?this.id = id;

? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ?}

? ?public class Student {

? ? ? ? private String name;

? ? ? ? private ArrayList courses;

? ? ? ? public Student(String name, ArrayList courses) {

? ? ? ? ? ? ? this.name = name;

? ? ? ? ? ? ?this.courses = courses;

? ? ? ? }

? ? ? ?public String getName() {

? ? ? ? ? ? return name;

? ? ? ? }

? ? ? ?public void setName(String name) {

? ? ? ? ? ?this.name = name;

? ? ? ? ?}

? ? ? public ArrayList getCourses() {

? ? ? ? ? return courses;

? ? ? ? }

? ? ?public void setCourses(ArrayList courses) {

? ? ? ? ?this.courses = courses;

? ? ? ?}

? ? }

? ? private void student() {

? ? ? ? ? Course yuwen = new Course("語文", 1);

? ? ? ? ? Course shuxue = new Course("數(shù)學", 2);

? ? ? ? ? Course yingyu = new Course("英文", 3);

? ? ? ? ? Course lishi = new Course("歷史", 4);

? ? ? ? ?Course zhengzhi = new Course("政治", 5);

? ? ? ? ?Course xila = new Course("希臘語", 6);

? ? ? ? ?ArrayList course1 = new ArrayList<>();

? ? ? ? ?course1.add(yuwen);

? ? ? ? ?course1.add(shuxue);

? ? ? ? ?course1.add(yingyu);

? ? ? ? ?course1.add(lishi);

? ? ? ? course1.add(zhengzhi);

? ? ? ? course1.add(xila);

? ? ? ? Student zhangsan = new Student("zhangsan", course1);

? ? ? ? Observable.just(zhangsan)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .flatMap(new Func1>() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?public Observable call(Student student) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return Observable.from(student.getCourses());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }).subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?public void call(Course course) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(course.getName());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?});

? ? ? ? ? ? ? ? ? ? ? }

8.和Retrofit一起使用

1.添加依賴:

compile 'com.squareup.retrofit2:retrofit:2.0.1'

compile 'com.squareup.retrofit2:converter-gson:2.0.1'

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'

2.利用http://www.jsonschema2pojo.org創(chuàng)建數(shù)據(jù)模型

3.創(chuàng)建REST API 接口.注意此時返回的不能是Call而是Observable.示例代碼:

public interface LocationInterface {

? ? ? ? ? // http://ip.taobao.com/service/getIpInfo.php?ip=202.178.10.23

? ? ? ? ?@GET("/service/getIpInfo.php")

? ? ? ? ?public Observable getLocation(@Query("ip") String ip);

? }

4.創(chuàng)建Retrofit對象,發(fā)起請求.注意此時Retrofit需要添加addCallAdapterFactory.示例代碼:

? ? ? ? ? Retrofit retrofit = new Retrofit.Builder()

? ? ? ? ? ? ? ? ? ? ? .baseUrl(BASE2)

? ? ? ? ? ? ? ? ? ? ? .addConverterFactory(GsonConverterFactory.create())

? ? ? ? ? ? ? ? ? ? ? .addCallAdapterFactory(RxJavaCallAdapterFactory.create())

? ? ? ? ? ? ? ? ? ? ? .build();

? ? ? ? LocationInterface locationInterface = retrofit.create(LocationInterface.class);

? ? ? ?Observable location = locationInterface.getLocation("8.8.8.8");

? ? ? ? ? ? ? ? ? ? ? location

? ? ? ? ? ? ? ? ? ? ?.subscribeOn(Schedulers.io())

? ? ? ? ? ? ? ? ? ? .map(new Func1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public String call(Location location) {

? ? ? ? ? ? ? ? ? ? ? ? return location.getData().getCountry();

? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ?.observeOn(AndroidSchedulers.mainThread())

? ? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? ? ? ? ?textView.setText(s);

? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ?});

? ? ? ? 以上就是這次整理的內容厚脉,整體來說就一個框架的內容,就是響應式編程的介紹胶惰,不夠我對這個東西算不上是熟悉的傻工,因為確實

沒有在正式的項目中使用過這個東西,但從平常的測試實踐中感覺這個確實對設計和解耦非常有幫助孵滞,不過自從看了kotlin之后精钮,覺得

這個東西就稍微差了一點點,這個東西仁者見仁智者見智吧剃斧,希望有研究過的小伙伴兒看一下轨香,有什么不對的地方及時的指正,一起分享

學習一下幼东。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末臂容,一起剝皮案震驚了整個濱河市科雳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脓杉,老刑警劉巖糟秘,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異球散,居然都是意外死亡尿赚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門蕉堰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌净,“玉大人,你說我怎么就攤上這事屋讶”埃” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵皿渗,是天一觀的道長斩芭。 經常有香客問我,道長乐疆,這世上最難降的妖魔是什么划乖? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮挤土,結果婚禮上琴庵,老公的妹妹穿的比我還像新娘。我一直安慰自己耕挨,他們只是感情好细卧,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著筒占,像睡著了一般贪庙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翰苫,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天止邮,我揣著相機與錄音,去河邊找鬼奏窑。 笑死导披,一個胖子當著我的面吹牛,可吹牛的內容都是我干的埃唯。 我是一名探鬼主播撩匕,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼墨叛!你這毒婦竟也來了止毕?” 一聲冷哼從身側響起模蜡,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扁凛,沒想到半個月后忍疾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡谨朝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年卤妒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片字币。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡则披,死狀恐怖,靈堂內的尸體忽然破棺而出纬朝,到底是詐尸還是另有隱情收叶,我是刑警寧澤骄呼,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布共苛,位于F島的核電站,受9級特大地震影響蜓萄,放射性物質發(fā)生泄漏隅茎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一嫉沽、第九天 我趴在偏房一處隱蔽的房頂上張望辟犀。 院中可真熱鬧,春花似錦绸硕、人聲如沸堂竟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽出嘹。三九已至,卻和暖如春咬崔,著一層夾襖步出監(jiān)牢的瞬間税稼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工垮斯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留郎仆,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓兜蠕,卻偏偏與公主長得像扰肌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熊杨,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容

  • 文章轉自:http://gank.io/post/560e15be2dca930e00da1083作者:扔物線在正...
    xpengb閱讀 7,020評論 9 73
  • 前言我從去年開始使用 RxJava 曙旭,到現(xiàn)在一年多了墩剖。今年加入了 Flipboard 后,看到 Flipboard...
    占導zqq閱讀 9,158評論 6 151
  • 版權聲明:本文為小斑馬偉原創(chuàng)文章夷狰,轉載請注明出處岭皂! 上篇簡單的闡述了響應式編程的基本理論。這篇主要對響應編程進行詳...
    ZebraWei閱讀 2,214評論 0 2
  • 我從去年開始使用 RxJava 沼头,到現(xiàn)在一年多了爷绘。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy閱讀 5,456評論 7 62
  • 文/楓梓_sail 昨天趕完活動已經很晚进倍,回來洗漱睡覺土至,竟意外的一夜好眠,忘記有多久沒有這么踏實的睡過了猾昆,胡思亂想...
    楓梓_sail閱讀 368評論 0 4