RxAndroid簡述
Rx是響應式編程的意思, 本質是觀察者模式, 是以觀察者(Observer)和訂閱者(Subscriber)為基礎的異步響應方式. 在Android編程時, 經常會使用后臺線程, 那么就可以使用這種方式. 目前的異步編程方式都會導致一些問題, 如
(1) Asynctasks can easily lead to memory leaks. (2) CursorLoaders with a ContentProvider require a large amount of configuration and boilerplate code to setup. (3) Services are intended for longer running background tasks and not fast-finishing operations, such as making a network call or loading content from a database.
RxAndroid來源于RxJava, 在RxJava的基礎上擴展了一些Android的功能, 已經發布1.0版本, 讓我們來看看怎么用吧.
1. 準備
新建一個HelloWorld程序. 配置build.gradle
, 添加RxAndroid庫和Lamada表達式支持, 還有ButterKnife.
plugins { id "me.tatarka.retrolambda" version "3.2.2" } ... android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { ... compile 'com.jakewharton:butterknife:7.0.1' compile 'io.reactivex:rxandroid:1.0.1' }
Lambda表達式支持不是必須的, 可以讓你代碼更加簡潔, 減少匿名類的出現.
2. 頁面
頁面很簡單, 設置三個按鈕, 觸發耗時的線程操作, 分別用主線程, Asynctasks
, Rx方式調用, 觀察ProcessBar的狀態.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".MainActivity" tools:showIn="@layout/activity_main"> <Button android:id="@+id/main_thread" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="主線程"/> <Button android:id="@+id/main_async" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/main_thread" android:layout_centerHorizontal="true" android:text="Asynctasks"/> <Button android:id="@+id/main_rx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/main_async" android:layout_centerHorizontal="true" android:text="Rx"/> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminate="true" android:layout_centerVertical="true" android:layout_centerHorizontal="true"/> </RelativeLayout>
3. 邏輯
添加一個阻塞任務, 執行5秒, 成功反饋.
// 長時間運行的任務 private String longRunningOperation() { try { Thread.sleep(5000); } catch (Exception e) { Log.e("DEBUG", e.toString()); } return "Complete!"; }
主線程執行時, 會導致UI卡頓
// 線程運行 mThreadButton.setOnClickListener(v -> { mThreadButton.setEnabled(false); longRunningOperation(); Snackbar.make(mRootView, longRunningOperation(), Snackbar.LENGTH_LONG).show(); mThreadButton.setEnabled(true); });
異步線程執行
// 異步線程 private class MyAsyncTasks extends AsyncTask<Void, Void, String> { @Override protected void onPostExecute(String s) { Snackbar.make(mRootView, s, Snackbar.LENGTH_LONG).show(); mAsyncButton.setEnabled(true); } @Override protected String doInBackground(Void... params) { return longRunningOperation(); } }
// 異步運行 mAsyncButton.setOnClickListener(v -> { mAsyncButton.setEnabled(false); new MyAsyncTasks().execute(); });
響應式方式執行, 使用IO線程處理, 主線程響應, 也可以使用其他線程處理, 如Schedulers.io()
處理IO的線程, Schedulers.computation()
計算的線程, Schedulers.newThread()
新創建的線程.
// 使用IO線程處理, 主線程響應 Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext(longRunningOperation()); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()); // 響應式運行 mRxButton.setOnClickListener(v -> { mRxButton.setEnabled(false); observable.subscribe(new Subscriber<String>() { @Override public void onCompleted() { mRxButton.setEnabled(true); } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { Snackbar.make(mRootView, s, Snackbar.LENGTH_LONG).show(); } }); });
使用響應式編程可以更好的處理內存泄露問題, 代碼也更加優雅和可讀, 選擇執行線程和監聽線程也更加方便. 在destroy時, 可以關閉正在執行的異步任務. 還有一些其他優勢, 就參考網站吧.
OK, 使用響應式這種好用的異步編程方式吧.
來自: http://blog.csdn.net//caroline_wendy/article/details/49721591
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!