前幾天講了兩個強大的涵式庫,分別是處理Http連線的Retrofit以及處理資料庫的Room,這兩個強大的工具雖然說已經很實用了,不過他們兩個都有一個共通點,就是執行式通常需要開啟線程,負責處理耗時的工作。那這樣豈不是和我們RxJava很合得來嗎,我們今天就來看看經過這樣的結合後,會產生怎麼樣的化學變化呢~?
既然知道RxJava是負責做線程切換,那麼我們就著重在需要切換線程的功能上。
//一定要有回傳值
@GET("posts/1")
Single<Post> getPosts();
//不一定要有回傳值
@POST("posts")
Maybe<Response<Post>> createPost(@Body Post post); //用Body表示要傳送Body的資料
//Get
//工作的執行緒,rx的background thread,適合用來處理網路連線、資料庫存取這些不使用CPU運算的作業
myAPIService.getPosts().subscribeOn(Schedulers.io())
//發射結果的執行緒,回到主線程,rx的ui thread
.observeOn(AndroidSchedulers.mainThread())
//訂閱
.subscribe(new SingleObserver<Post>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@androidx.annotation.NonNull Post post) {
StringBuilder result = new StringBuilder();
result.append("{").append("\n");
//獲取資料,並整理
result.append("ID: ").append(post.getId()).append("\n") ;
result.append("User ID: ").append(post.getUserId()).append("\n") ;
result.append("Title: ").append(post.getTitle()).append("\n") ;
result.append("Text: ").append(post.getText()).append("\n");
result.append("},").append("\n");
result_txt.setText(content);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "發生錯誤:"+e.getMessage());
}
});
//Post
Post post = new Post(23,"New Title","New Text");
Maybe<Response<Post>> observable = myAPIService.createPost(post);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new MaybeObserver<Response<Post>>() {
@Override
public void onSubscribe(@NonNull Disposable d){
Log.d(TAG, "訂閱");
}
@Override
public void onSuccess(@androidx.annotation.NonNull Response<Post> postResponse) {
Post post = postResponse.body();
StringBuilder result = new StringBuilder();
result.append("{").append("\n");
//獲取資料,並整理
result.append("ID: ").append(post.getId()).append("\n") ;
result.append("User ID: ").append(post.getUserId()).append("\n") ;
result.append("Title: ").append(post.getTitle()).append("\n") ;
result.append("Text: ").append(post.getText()).append("\n");
result.append("},").append("\n");
result_txt.setText(result);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "發生錯誤:"+e.getMessage());
}
@Override
public void onComplete() {
//完成時進入
Log.d(TAG, "完成:");
}
});
這樣我們就完成讓API的連線在背景線程,回調結果再回到主線程,這樣集結合Retrofit是不是又更上一層樓了呢~
了解以上的話,我們接續往下看。
//僅回覆成功失敗
@Insert(onConflict = OnConflictStrategy.REPLACE)
Completable insertAccount(MyAccount myAccount);
//有回傳
@Query("SELECT * FROM " + tableName)
Observable<List<MyAccount>> getAllAccount();
//僅回覆成功失敗
@Update
Completable updateAccount(MyAccount myAccount);
//僅回覆成功失敗
@Delete
Completable deleteData(MyData myData);
//Observable
DataBase.getInstance(mContext).getAccountDao().getAllAccount()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<MyAccount>>() {
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
//發生訂閱時
}
@Override
public void onNext(@io.reactivex.annotations.NonNull List<MyAccount> myData) {
//回傳結果時
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
//發生錯誤時
}
@Override
public void onComplete() {
//執行完成時
}
});
//Completable
DataBase.getInstance(mContext).getAccountDao().updateAccount(data)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//發生訂閱時
}
@Override
public void onError(@NonNull Throwable e) {
//失敗
}
@Override
public void onComplete() {
//完成
}
});
如此一來,Room也完成了與RxJava的集合,再使用Room上也變得更放變了呢~
結合的方式大同小異,都是將需要耗時的工作轉成Observable,並對應回傳結果選擇好型態,最後呼叫此會回傳Observable類型的方法並設定subscribeOn(執行線程)及observeOn(回調時的線程),最後subscribe()即可完成,有在使用Room和Retrofit的同學真的建議趕緊試試看,我個人是試過就回不去了~