首頁 Java java教程 【Android】RxJava之初始篇

【Android】RxJava之初始篇

Nov 15, 2016 am 10:12 AM
rxjava

關於RxJava

RxJava是ReactiveX推出在Java VM環境下使用的非同步操作庫。除了在Java環境ReactiveX也為其他程式語言推出Rx函式庫,例如Py、Js、Go等。網路上有很多關於對RxJava的介紹和使用,在Android開發中也有很多專案使用RxJava。那為什麼還要使用RxJava呢,Android開發也有提供非同步操作的方法供開發者使用,我想應該是RxJava比起Handle、AsyncTask簡潔優雅。

1 RxJava採用鍊式調用,在程式邏輯上清晰簡潔

2 採用擴展式觀察者設計模式

關於觀察者模式以及其他RxJava的介紹這個就不做重複,下面內容主要圍繞RxJava和RxAndroid使用。對於RxJava官方文件已經有詳細介紹,本節是以學習討論為主,如有錯誤的地方希望大家可以指出。

被觀察者Observable

使用RxJava需要建立Observable,Observable用來發射資料。如下Observable的create方法需要傳入一個OnSubscribe,其繼承於Action1>,Action中的Subscriber就是訂閱者。

public static <T> Observable<T> create(OnSubscribe<T> f) { 
    return new Observable<T>(RxJavaHooks.onCreate(f)); 
}
登入後複製

另外create方法中需要實作介面call,回傳subscriber物件。 call方法實作在observable訂閱後要執行的事件流。 subscriber.onNext發射data,subscriber.onCompleted可以表示發射事件結束。接著呼叫observable的subscribe方法實作被訂閱後執行的事件流。

Observable<String> observable = Observable 
                .create(new Observable.OnSubscribe<String>() { 
 
            @Override 
            public void call(Subscriber<? super String> subscriber) { 
                subscriber.onNext("1"); 
                subscriber.onNext("2"); 
                subscriber.onNext("3"); 
                subscriber.onNext("4"); 
                subscriber.onNext("5"); 
            } 
}); 
Subscriber<String> subscriber = new  Subscriber<String>() { 
            @Override 
            public void onCompleted() { 
 
            } 
 
            @Override 
            public void onError(Throwable e) { 
 
            } 
 
            @Override 
            public void onNext(String s) { 
                System.out.print(s + &#39;\n&#39;); 
            } 
}; 
observable.subscribe(subscriber); 
//输出结果 print: 
//1 
//2 
//3 
//4 
//5
登入後複製

Observable除了使用create方法建立外還可以使用from或just快速設定發射的事件流,簡化了create的步驟。

【Android】RxJava之初始篇

Observable<String> o = Observable.from("a", "b", "c");
登入後複製

【Android】RxJava之初始篇

Observable<String> o = Observable.just("one object");
登入後複製

說好的非同步操作

RxJava的執行緒由Schedulers調度者控制,並透過它來控制具體操作在什麼執行緒中進行。

Schedulers.immediate() 在當前執行緒中執行

Schedulers.newThread() 為每個任務開闢執行緒執行

Schedulers.computation() 計算任務執行的執行緒

....

AndroidSchedulers.mainThread() Android 主執行緒運行

對於執行緒的控制主要由subscribeOn()和observeOn()兩個方法控制:

subscribeOn 控制Observable.OnSubscribe所處的執行緒,等同於Oservbable. create、just、from時所處的線程。

observeOn 控制Subscriber的線程,也可以說是控制事件被執行時所在的線程。

Observable 
        .just(1,2,3) 
        .subscribeOn(Schedulers.io()) 
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(new Subscriber<Integer>() { 
            @Override 
            public void onCompleted() { 
 
            } 
 
            @Override 
            public void onError(Throwable e) { 
 
            } 
 
            @Override 
            public void onNext(Integer integer) { 
                 System.out.print(integer + &#39;\n&#39;);                        
            } 
}); 
//输出结果 print: 
//1 
//2 
//3
登入後複製

寫下上面的RxJava鍊式調用的代碼,有沒有覺得比以前使用的異步調用清爽許多,對處女座還說這很治愈!

操作符Operators

ReactiveX提供超級多的操作符,提供超級多的操作符每個操作符都有不同的功能,但目的都是在Observable和Subscribe之間變換和修改發射出去的事件流。這節介紹幾個比較常見簡單的操作符,之後有機會再寫一節操作符篇詳細說說每個操作符的作用。附上官方操作符文件看看就知道有多少多了。

Map() 

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

【Android】RxJava之初始篇

先介紹一個操作符map,map實作Func1介面將T型別資料轉換為R型數據,回傳R型數據。例如傳入Integer類型的事件佇列,經過map加工後再以String類型傳回。

Observable 
                .just(1,2,3) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                    ...... 
                    @Override 
                    public void onNext(String str) { 
                        System.out.print(str + &#39;\n&#39;); 
                    } 
                }); 
//输出结果 print: 
//1 
//2 
//3
登入後複製

Filter() 

public final Observable<T> filter(Func1<? super T, Boolean> predicate) { 
       return create(new OnSubscribeFilter<T>(this, predicate)); 
   }
登入後複製

【Android】RxJava之初始篇

filter和map一樣實現Func1介面不過它變換之後的類型為boolean,對發射的事件流進行篩選,當變換後的boolean值為true,訂閱者才能收到透過篩選的事件,反之該事件不被消費。例如事件流篩選要求當int值可被2整除才能繼續傳遞,所以最後訂閱者可消費的事件為2,4,6,8,10。

Observable 
                .just(1,2,3,4,5,6,7,8,9,10) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .filter(new Func1<Integer, Boolean>() { 
                    @Override 
                    public Boolean call(Integer integer) { 
                        return integer % 2 == 0; 
                    } 
                }) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                   ...... 
                    @Override 
                    public void onNext(String str) { 
                        System.out.print(str + &#39;\n&#39;); 
                        Log.i("subscribe", str); 
                    } 
                }); 
//输出结果 print: 
//2 
//3 
//4 
//6 
//8 
//10
登入後複製

Skip()

public final Observable<T> skip(int count) { 
        return lift(new OperatorSkip<T>(count)); 
    }
登入後複製

【Android】RxJava之初始篇

skip操作符表示跳過前幾個事件從某一個事件開始發射事件,下標從0開始。

Observable 
                .just(1,2,3,4,5,6,7,8,9,10) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .skip(3) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                    ...... 
                    @Override 
                    public void onNext(String s) { 
                        System.out.print(s + &#39;\n&#39;); 
                        Log.i("subscribe", s); 
                    } 
                }); 
//输出结果 print: 
//4 
//5 
//6 
//7 
//8 
//9 
//10
登入後複製

Range()

public static Observable<Integer> range(int start, int count) { 
        if (count < 0) { 
            throw new IllegalArgumentException("Count can not be negative"); 
        } 
        if (count == 0) { 
            return Observable.empty(); 
        } 
        if (start > Integer.MAX_VALUE - count + 1) { 
            throw new IllegalArgumentException("start + count can not exceed Integer.MAX_VALUE"); 
        } 
        if(count == 1) { 
            return Observable.just(start); 
        } 
        return Observable.create(new OnSubscribeRange(start, start + (count - 1))); 
    }
登入後複製

【Android】RxJava之初始篇

range運算子可以理解為just,from傳遞一個連續的int型別待發射數組,n為起始int值,m為Count。例如n = 1,m = 5 int數組就是{1,2,3,4,5}

結尾

這節先學習到這,算是對RxJava的初步認識與學習。其實運用RxJava主要還是依賴對操作符的使用,前面所介紹的操作符屬於最簡單基礎的,還有很多特別有用的操作符沒有介紹。之後再繼續介紹一些操作符。 RxJava在Android開發中很受歡迎,就是因為它的強大,同時RxJava可以和Retrofit組合使用,更有效率處理網路請求回值。另外GitHub GoogleSample上的android-architecture也有使用RxJava框架的TODO項目,可以看看理解RxJava在專案中的實作應用。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

公司安全軟件導致應用無法運行?如何排查和解決? 公司安全軟件導致應用無法運行?如何排查和解決? Apr 19, 2025 pm 04:51 PM

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

如何使用MapStruct簡化系統對接中的字段映射問題? 如何使用MapStruct簡化系統對接中的字段映射問題? Apr 19, 2025 pm 06:21 PM

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

如何優雅地獲取實體類變量名構建數據庫查詢條件? 如何優雅地獲取實體類變量名構建數據庫查詢條件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

如何將姓名轉換為數字以實現排序並保持群組中的一致性? 如何將姓名轉換為數字以實現排序並保持群組中的一致性? Apr 19, 2025 pm 11:30 PM

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本啟動Spring...

Java對像如何安全地轉換為數組? Java對像如何安全地轉換為數組? Apr 19, 2025 pm 11:33 PM

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? 電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? Apr 19, 2025 pm 11:27 PM

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名構建查詢條件? 使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名構建查詢條件? Apr 19, 2025 pm 09:51 PM

在使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名以構建查詢條件,是一個常見的難題。本文將針...

See all articles