這是之前保存的學習筆記, 現在上傳保存一下
Rxjava
1,創建觀察者: observer subscriber
Observer 即觀察者,它決定事件觸發的時候將有怎樣的行爲。 RxJava 中的 Observer 接口的實現方式:
Observer<String> observer = new Observer<String>() {
@Override
public void onNext(String s) {
Log.d(tag, "Item: " + s);
}
@Override
public void onCompleted() {
Log.d(tag, "Completed!");
}
@Override
public void onError(Throwable e) {
Log.d(tag, "Error!");
}
};
2,創建被觀察者: observable
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("Hi");
subscriber.onNext("Aloha");
subscriber.onCompleted();
}
});
可以看到,這裏傳入了一個 OnSubscribe 對象作爲參數。
OnSubscribe 會被存儲在返回的 Observable 對象中,它的作用相當於一個計劃表,
當 Observable 被訂閱的時候,OnSubscribe 的 call() 方法會自動被調用.
事件序列就會依照設定依次觸發(對於上面的代碼,就是觀察者Subscriber 將會被調用三次 onNext() 和一次 onCompleted())。
這樣,由被觀察者調用了觀察者的回調方法,就實現了由被觀察者向觀察者的事件傳遞,即觀察者模式。
創建方式:
1.observable.create(Onsubscriber)
create() 方法是 RxJava 最基本的創造事件序列的方法。 見上邊的代碼 使用 create創建的 observable
2.observable.just(T …)
基於create()方法, RxJava 還提供了一些方法用來快捷創建事件隊列
例如:
Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 將會依次調用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
3.obserbable.from(arraylist<>)
from(T[]) / from(Iterable
與 Retrofit 的結合
@GET("/user")
public void getUser(@Query("userId") String userId, Callback<User> callback);
PS: retrifit中 baseurl後面跟 /user : 這裏不推薦這樣寫 ,最好的寫法應該是 @GET("user"),這樣簡單易用不易出問題
這是接口中的方法,用來回去用戶信息的, get請求, query參數代表了要 請求最終爲: /user?userId=23 這種形式
在程序的構建過程中, Retrofit 會把自動把方法實現並生成代碼,然後開發者就可以利用下面的方法來獲取特定用戶並處理響應:
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
注 : 這應該是 retrofit 1.x的了, retrofit2 的版本直接會返回call而不能用void方法
而使用 RxJava 形式的 API,定義同樣的請求是這樣的:
@GET("/user")
public Observable<User> getUser(@Query("userId") String userId);
這個時候已經獲取到 Observable對象了 ,即已經獲取到 被觀察者了 ,可以進行subscribe進行訂閱了
getUser(userId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
當 RxJava 形式的時候,Retrofit 把請求封裝進 Observable ,在請求結束後調用 onNext() 或在請求失敗後調用 onError()。
你的程序取到的 User 並不應該直接顯示,而是需要先與數據庫中的數據進行比對和修正後再顯示。使用 Callback 方式大概可以這麼寫
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
processUser(user); // 嘗試修正 User 數據
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
這是callback的方式, 並不方便因爲這樣做會影響性能。數據庫的操作很重,一次讀寫操作花費 10~20ms 是很常見的,這樣的耗時很容易造成界面的卡頓。所以通常情況下,如果可以的話一定要避免在主線程中處理數據庫。所以爲了提升性能,這段代碼可以優化一下:
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
new Thread() {
@Override
public void run() {
processUser(user); // 嘗試修正 User 數據
runOnUiThread(new Runnable() { // 切回 UI 線程
@Override
public void run() {
userView.setUser(user);
}
});
}).start();
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
性能問題解決,但……這代碼實在是太亂了,迷之縮進啊!雜亂的代碼往往不僅僅是美觀問題,因爲代碼越亂往往就越難讀懂,而如果項目中充斥着雜亂的代碼,無疑會降低代碼的可讀性,造成團隊開發效率的降低和出錯率的升高。
如果用 RxJava 的形式,就好辦多了。 RxJava 形式的代碼是這樣的:
getUser(userId)
.doOnNext(new Action1<User>() {
@Override
public void call(User user) {
processUser(user);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
後臺代碼和前臺代碼全都寫在一條鏈中,明顯清晰了很多。
例子2
假設 /user 接口並不能直接訪問,而需要填入一個在線獲取的 token ,代碼應該怎麼寫?
Callback 方式,可以使用嵌套的 Callback:
@GET("/token")
public void getToken(Callback<String> callback);
@GET("/user")
public void getUser(@Query("token") String token, @Query("userId") String userId, Callback<User> callback);
getToken(new Callback<String>() {
@Override
public void success(String token) {
getUser(token, userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
});
倒是沒有什麼性能問題,可是迷之縮進毀一生,你懂我也懂,做過大項目的人應該更懂。
而使用 RxJava 的話,代碼是這樣的:
@GET("/token")
public Observable<String> getToken();
@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
...
getToken()
.flatMap(new Func1<String, Observable<User>>() {
@Override
public Observable<User> onNext(String token) {
return getUser(token, userId);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
用一個 flatMap() 就搞定了邏輯,依然是一條鏈