RxJava到底是什麼?使用RxJava到底有什麼好處呢?其實RxJava是ReactiveX中使用Java語言實現的版本,目前ReactiveX已經實現的語言版本有:
Java: RxJava
JavaScript: RxJS
C#: Rx.NET
C#(Unity): UniRx
Scala: RxScala
Clojure: RxClojure
C++: RxCpp
Ruby: Rx.rb
Python: RxPY
Groovy: RxGroovy
JRuby:RxJRuby
Kotlin: RxKotlin
可以看出ReactiveX在開發應用中如此的火爆。那到底什麼是ReactiveX呢?簡單來說,ReactiveX就是」觀察者模式+迭代器模式+函數式編程」,它擴展了觀察者模式,通過使用可觀察的對象序列流來表述一系列事件,訂閱者進行占點觀察並對序列流做出反應(或持久化或輸出顯示等等);借鑒迭代器模式,對多個對象序列進行迭代輸出,訂閱者可以依次處理不同的對象序列;使用函數式編程思想(functional programming),極大簡化問題解決的步驟。
2. Android RxJava使用完對象之後怎麼處理
事件是傳遞的最小單位,可以把任何類作為一個事件。
RxBus代碼如下:
/** * Author: wangjie * Email: [email protected] * Date: 6/11/15. */public class RxBus { private static final String TAG = RxBus.class.getSimpleName(); private static RxBus instance; public static boolean DEBUG = false; public static synchronized RxBus get() { if (null == instance) { instance = new RxBus(); } return instance; } private RxBus() { } private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>(); @SuppressWarnings("unchecked") public <T> Observable<T> register(@NonNull Object tag, @NonNull Class<T> clazz) { List<Subject> subjectList = subjectMapper.get(tag); if (null == subjectList) { subjectList = new ArrayList<>(); subjectMapper.put(tag, subjectList); } Subject<T, T> subject; subjectList.add(subject = PublishSubject.create()); if (DEBUG) Log.d(TAG, "[register]subjectMapper: " + subjectMapper); return subject; } public void unregister(@NonNull Object tag, @NonNull Observable observable) { List<Subject> subjects = subjectMapper.get(tag); if (null != subjects) { subjects.remove((Subject) observable); if (ABTextUtil.isEmpty(subjects)) { subjectMapper.remove(tag); } } if (DEBUG) Log.d(TAG, "[unregister]subjectMapper: " + subjectMapper); } public void post(@NonNull Object content) { post(content.getClass().getName(), content); } @SuppressWarnings("unchecked") public void post(@NonNull Object tag, @NonNull Object content) { List<Subject> subjectList = subjectMapper.get(tag); if (!ABTextUtil.isEmpty(subjectList)) { for (Subject subject : subjectList) { subject.onNext(content); } } if (DEBUG) Log.d(TAG, "[send]subjectMapper: " + subjectMapper); }}
如上述代碼,RxBus只提供了register、unregister、post三個方法。
這里又加入了一個tag的概念,也可以理解為channel,注冊Subject、反注冊Subject和post事件的時候都需要這個tag,只有tag一致才能正常接收到事件。
比如有一個事件類HelloEvent,這個事件的作用是接收到後toast一個提示「hello」,如果兩個Activity都注冊了這個HelloEvent事件,但是沒有tag去限制,一旦post了一個helloEvent事件後,兩個Activity都會收到這個事件,導致兩個Activity都會toast。如果使用tag,post這個HelloEvent的時候可以設置這個tag,只有register時也使用了這個tag才會接收到這個event。
2. 在Present(如Activity的onCreate)中注冊一個Observer(以下以發送一個String類型的事件為例)
Observable<String> addOb = RxBus.get() .register("addFeedTag", String.class); addOb.observeOn(AndroidSchelers.mainThread()) .subscribe(s -> { // todo: Accept event and process here });
如上,注冊了一個String類型的事件,事件的tag是「addFeedTag」,用來增加一個Feed。使用RxAndroid在Action1中處理接收到的這個事件。
3. 在任何地方發送一個事件:
RxBus.get().post("addFeedTag", "hello RxBus!");
這里發送了一個tag為「addFeedTag」的String類型的事件。
4. 反注冊Observer:
RxBus.get().unregister("addFeedTag", addOb);
注意:這里的Tag都為「addFeedTag」。
下面使用註解的方式更簡單方便地使用RxBus(嗯-。-這里才是重點)。
首先來看下使用註解後的代碼:
1. 注冊Observer
這一步可以省略掉。
2. 發送一個事件(這里我們換一個事件:FeedItemCl3. ickEvent,我們定義這個事件是用來處理當Feed被點擊後的事件)
RxBus.get().post(new FeedItemClickEvent().setPosition(position).setFeed(feed));
3. 接收事件,然後處理
1 @Accept2 public void onPostAccept(Object tag, FeedItemClickEvent event) {3 Logger.d(TAG, "onPostAccept event: " + event);4 Feed feed = event.getFeed();5 // 跳轉到feed詳情頁面...6 }
如上,這里只需要編寫一個方法,加上Accept註解,然後在方法中進行事件處理即可。
注意:方法名可以任意
方法參數一:必須為Object類型的tag;
方法參數二,如果這個方法只接收一種事件,則寫明具體的事件類型,如上;如果這個方法接收多種事件,則類型需要為Object。
4. 反注冊Observer
這一步也可以省略掉。
接收多種事件:
@Accept( acceptScheler = AcceptScheler.NEW_THREAD, value = { @AcceptType(tag = ActionEvent.CLOSE, clazz = String.class), @AcceptType(tag = ActionEvent.BACK, clazz = String.class), @AcceptType(tag = ActionEvent.EDIT, clazz = String.class), @AcceptType(tag = ActionEvent.REFRESH, clazz = String.class) } ) public void onPostAccept(Object tag, Object actionEvent) { Logger.d(TAG, "[ActionEvent]onPostAccept action event name: " + actionEvent); // todo: Accept event and process here (in new thread) }
這里@Accept註解中設置了acceptScheler為AcceptScheler.NEW_THREAD,指明方法運行在子線程中.
value中指明了接收的事件類型,這里表示這個方法接收4種類型的事件:CLOSE, BACK, EDIT, REFRESH.
註解解釋:
@Accept註解
acceptScheler: 指定被註解的方法運行的Scheler。
value[]: AcceptType註解數組,用於指定接收事件的tag和class。
@AcceptType註解:
tag: 接收事件的tagclazz: 接收事件的類型
AcceptScheler:
詳情見:rx.schelers.Schelers和rx.android.schelers.AndroidSchelers
如果設置的是AcceptScheler.EXECUTOR或AcceptScheler.HANDLER,則需要在Application中配置Executor和Handler:/** * Author: wangjie * Email: [email protected] * Date: 6/15/15. */public class MyApplication extends Application { private Executor acceptExecutor = Executors.newCachedThreadPool(); private Handler handler = new Handler(Looper.getMainLooper()); @Override public void onCreate() { super.onCreate(); RxBus.DEBUG = true; DefaultAcceptConfiguration.getInstance().registerAcceptConfiguration(new DefaultAcceptConfiguration.OnDefaultAcceptConfiguration() { @Override public Executor applyAcceptExecutor() { return acceptExecutor; } @Override public Handler applyAcceptHandler() { return handler; } }); }}
3. android rxjava retrofit 怎麼設置本地緩存
android:layout_width="142dp" android:layout_height="36dp" 修改imagebutton上面兩個屬性就可以了
4. android 引入rxjava會使apk增大多少
android 引入rxjava會使apk增大一點點,只是一個jar包而已,不會大於2M的,放心使用。
5. rxandroid 生命周期什麼時候調用
Dagger2:依賴注入並不是什麼新技術,但是使用在Android確實一個新的嘗試。AndroidApp越來越被當成嚴肅的大型項目來構建,很多在以前大型伺服器開發上使用的技術都被應用到了移動開發。Android開發分模塊開發,使用Dagger來松耦合模塊。特別值得一體的是,Dagger2現在由Google親自接管。Dagger‡。MVP:因為Android並沒有嚴格的業務和界面區分,項目一復雜,就很容易使代碼陷入混亂。現在Android開發社區對MVP模式討論越來越熱,覺得MVP是非常適合AndroidAPP開發。MVPforAndroid:。RxAndroid:函數響應式編程(FunctionalReactiveProgramming)也不是新內容,RxAndroid把RxJava帶到Android環境中。很多時候,編寫Android程序,你也可以看成是數據的處理和流動,換一種思想編程,曾經看起來很棘手的問題,瞬間就很優雅的解決了:ReactiveX/RxAndroid。MVVM:這是因為開始官方支持DataBinding,把MVVM直接帶到Android中。數據綁定在WindowsWPF和Web已經非常常見,它非常高效的開發效率,讓你只關心你的數據和業務。這也對Android開發來說,無疑是一個非常重大的影響:androidUI設計MVVM設計模式討論?。插件化:針對大型Android項目,很多App開始使用插件來分模塊構建相對獨立的功能。Hybrid:完全使用HTML5開發App,目前還不成熟。但是折中方案在很多情況下是非常適合的,典型的就是微信,大部分信息展示都是通過H5來完成,同時通過Hybird方式,把Web和Native打通,提供給網頁訪問本地資源的能力。
6. android mvp rx為什麼要在presenter處理
RxAndroid可以簡單高度概括為「非同步」。
非同步操作很關鍵的一點是程序的簡潔性,因為在調度過程比較復雜的情況下,非同步代碼經常會既難寫也難被讀懂。Android 創造的 AsyncTask 和Handler ,其實都是為了讓非同步代碼更加簡潔。RxJava 的優勢也是簡潔,但它的簡潔的與眾不同之處在於,隨著程序邏輯變得越來越復雜,它依然能夠保持簡潔。
7. rxandroid和rxjava的區別
RxJava要比EventBus的應用更廣泛,EventBus僅僅是作為一種消息的傳遞工具,但是RxJava裡面幾乎可以做任何事情。
如果是Android開發的話,可以使用RxAndroid,這是對RxJava的一個擴展,結合sqare公司的retrofit可以很輕松的完成網路的訪問。
我們知道,在Android中非同步操作一般使用AsycTask來完成,但是AsycTask有很多缺點,如不能方便的終止任務的執行等。
RxAndroid完全可以替代AsycTask來完成各種非同步操作,而且還有BindActivity和BindFragment方法,你根本不需要考慮非同步操作時的Activity和Fragment的生命周期問題,還有更加強大的的鏈式調用,可以使程序很簡潔。
EventBus有個缺點就是凡是使用了EventBus的類都不能進行混淆了,否則Evnetbus就找不到OnEvent方法了。
以上,推薦使用RxAndroid。
8. android 用rxjava和retrofit時怎麼解決返回數據類型不一致
1. 首先定義帶泛型的返回結果,Retrofit API 的原生結果映射為這種形式:
class Result<T> {
String ResultMessage;
int ResultCode;
T Data;
}
2. 處理錯誤的方法和 @朱詩雄 前輩方法差不多,放到作為靜態方法放到 RetroUtil 里,這里 ApiException 為自己定義的一個異常,放入錯誤碼和錯誤信息(錯誤碼不止一個):
static <T> Observable<T> flatResult(Result<T> result) {
return Observable.create(subscriber -> {
switch (result.ResultCode) {
case Constants.SUCCESS_CODE:
subscriber.onNext(result.Data);
break;
case Constants.ERROR_CODE:
subscriber.onError(new ApiException(result.ResultCode, result.ResultMessage);
break;
default:
// ...
}
subscriber.onCompleted();
}
});
}
3. 在 API 包裝類對於上述 Result<T> 格式的返回結果,統一調用 flatMap(RetroUtil::flatResult) 後的 API。這樣每個 API 的返回結果就是 Observable<Data> 的形式並且在 errorHandler 中統一處理錯誤了。
// 介面方法
Observable<Result<User>> getUserInfo();
// 包裝後的方法
Observable<User> getUserInfo() {
return mApi.getUserInfo.flatMap(RetroUtil::flatResult);
}
// 調用時
apiWrapper.getUserInfo()
.subscrible(user -> {
// 處理正常邏輯
}, error -> {
// 處理錯誤邏輯和異常,這里封裝時通常也會統一處理,
// 提供一個默認的 Action1<Throwable> 參數,彈出
// throwable 的 message 列印日誌等
});
9. rxandroid和volley哪個好用
兩個不一樣的東西。rx是響應式編程,讓代碼更有條理性,針對復雜邏輯來說很好用。volley是谷歌官方出來的網路框架,針對大量的小數據請求應用。