iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Mobile Development

android studio 30天 精華筆記系列 第 25

精華筆記 Day25 - Retrofit+RxJava/Room+RxJava

  • 分享至 

  • xImage
  •  

前幾天講了兩個強大的涵式庫,分別是處理Http連線的Retrofit以及處理資料庫的Room,這兩個強大的工具雖然說已經很實用了,不過他們兩個都有一個共通點,就是執行式通常需要開啟線程,負責處理耗時的工作。那這樣豈不是和我們RxJava很合得來嗎,我們今天就來看看經過這樣的結合後,會產生怎麼樣的化學變化呢~?

既然知道RxJava是負責做線程切換,那麼我們就著重在需要切換線程的功能上。

Retrofit+RxJava

  • 負責進行API功能的interface,修改成以下。
//一定要有回傳值
@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是不是又更上一層樓了呢~

了解以上的話,我們接續往下看。

Room+RxJava

  • 負責進行資料庫的Dao(interface),修改成以下。
//僅回覆成功失敗
@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的同學真的建議趕緊試試看,我個人是試過就回不去了~


上一篇
精華筆記 Day 24 -Room
下一篇
精華筆記 Day26 - Dependency Injection(DI)
系列文
android studio 30天 精華筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言