一,什麼是Rx
1.Rx的基本介紹:Rx是響應式編程的意思,本質是觀察者模式,是以觀察者(Observer)和訂閱者(Subscriber)爲基礎的異步響應方式。
(1)縮寫:ReactiveX時Reactive Extensions的縮寫,一般簡寫爲Rx
(2)定義:Rx = Observables + LINQ + Schedulers. LINQ---語言集成查詢
(3)突破:ReactiveX不僅僅是一個編程接口,它是一種編程思想的突破,它影響了許多其它的程序庫和框架以及編程語言。
(4)Rx庫支持.Net,JavaScript,C++,常用有RxJava, RxJS, rx.NET
2.Rx模式以及優點:
<1>使用觀察者模式:
(1)創建:Rx可以方便的創建事件流和數據流
(2)組合:Rx使用查詢方式的操作符組合和變換數據流
(3)監聽:Rx可以訂閱任何可觀察的數據流並執行操作
<2>簡化代碼:
(1)函數式風格:對可觀察數據流使用無副作用的輸入輸出函數,避免了程序裏錯綜複雜的狀態
(2)簡化代碼:Rx的操作符通常可以將複雜的難題簡化爲很少的幾行代碼
(3)異步錯誤處理:傳統的try/catch沒辦法處理異常計算,Rx提供了合適的錯誤處理機制
(4)輕鬆使用併發:Rx的Observables和Schedulers讓開發者可以擺脫底層的線程同步和各種併發問題
3.Rx提供了什麼
(1)Rx提供了一些列的操作符,你可以使用它們來過濾(filter)、選擇(select)、變換(transform)、結合(combine)和組合(compose)多個Observable,
這些操作符讓執行和複合變得非常高效
(2)我們可以把Observable當做Iterable的推送方式的等價物,使用Iterable,消費者從生產者那拉取數據,線程阻塞直至數據準備好。
使用Observable,在數據準備好時,生產者將數據推送給消費者。數據可以同步或異步的到達,這種方式更靈活。
二,初始RxJava:
1.觀察者模式面向的需求:A對象(觀察者)對B對象(被觀察者)的某種變化高度敏感,需要在B變化的一瞬間作出反應(就是A監看B)
2.RxJava的四個基本概念:Observable(被觀察者)、Observer(觀察者)、subscrible(訂閱)、事件。
(1)Observable和Observer通過subscrible()方法實現訂閱關係,從而
Observable可以在需要的時候發出事件來通知Observer.
3.RxJava的基本實現:
(1)創建Observer
Observer即觀察者,它決定事件觸發的時候有怎樣的行爲。
RxJava中的Observer接口的實現方式。
(2)創建Observable
Observable即被觀察者,它決定什麼時候觸發事件以及觸發怎樣的事件。
RxJava使用create()方法來創建一個Observable,併爲它定義事件觸發規則
(3)Subscribe(訂閱)
創建了Observable和Observer之後,再創建subscribe()方法將他們聯結起來,整條鏈子就可以工作了
4,使用例子:
第一個例子:自定義接口實現:
(1)創建觀察者接口:定義監聽的方法
public interface Watcher {
//通過update()方法監聽到狀態的通知
public void update(String str);
}
(2)創建被觀察者接口:提供3個方法,添加觀察者,異常觀察者,通知提醒所以的觀察者
public interface Watched {
//添加觀察者
public void addWatcher(Watcher watcher);
//移除觀察者
public void removeWatcher(Watcher watcher);
//提醒所以的觀察者
public void notifyWatchers(String str);
}
(3)創建實現觀察者接口的觀察者類:
public class ConcreteWatcher implements Watcher {
@Override
public void update(String str) {
//打印出被觀察者的消息的變化
System.out.println(str);
}
}
(4)創建實現被觀察者接口的被觀察者類:用ArrayList來實現多個觀察者對象的監聽狀況
public class ConcreteWatched implements Watched {
//創建List集合
private List<Watcher> list = new ArrayList<>();
@Override
public void addWatcher(Watcher watcher) {
//添加觀察者對象
list.add(watcher);
}
@Override
public void removeWatcher(Watcher watcher) {
//移除觀察者對象
list.remove(watcher);
}
@Override
public void notifyWatchers(String str) {
//遍歷,通知所有觀察者被觀察對象的消息變化
for(Watcher watcher : list){
watcher.update(str);
}
}
}
(5)測試類:
public class Test {
public static void main(String[] args)throws Exception{
//新建一個被觀察者對象:小明
Watched xiaoming = new ConcreteWatched();
//新建3個觀察者來監聽小明的狀態
Watcher watcher1 = new ConcreteWatcher();
Watcher watcher2 = new ConcreteWatcher();
Watcher watcher3 = new ConcreteWatcher();
//把監聽器安裝在小明身上
xiaoming.addWatcher(watcher1);
xiaoming.addWatcher(watcher2);
xiaoming.addWatcher(watcher3);
//小明的狀改變了
xiaoming.notifyWatchers("我打算要偷東西了");
}
}
輸出如下:
我打算要偷東西了
我打算要偷東西了
我打算要偷東西了
第二個例子:利用Observable和Observer這兩個類來實現
import java.util.Observable;
import java.util.Observer;
需要配置builde.gradle(app)環境,添加如下兩行(這裏先把RxAndroid的一起添加了)
compile 'io.reactivex:rxandroid:1.1.0' // RxAndroid
compile 'io.reactivex:rxjava:1.1.0' // 推薦同時加載RxJava
(1)創建SimpleObservable類,繼承Observable類:
在裏面定義一個數據data,並創建getData()方法,和setData()方法,
再在setData()方法裏面設置狀態改變監聽與通知觀察者的方法,如下:
//設置狀態改變
setChanged();
//表示狀態改變,通知觀察者
notifyObservers();
整體代碼:
import java.util.Observable;
/**
* Created by maiyu on 2017/6/18.
* 創建一個被觀察者類
*/
public class SimpleObservable extends Observable {
//定義一個數據
private int data = 0;
//get方法
public int getData() {
return data;
}
/**
* setData方法
* @param i
*/
public void setData(int i) {
if(this.data != i) {
this.data = i;
//設置狀態改變
setChanged();
//表示狀態改變,通知觀察者
notifyObservers();
}
}
}
(2)創建觀察者類:SimpleObserver類,繼承Observer:
初始化構造方法(把被觀察者作爲參數),重寫update方法
在update裏實現通知,代碼如下:
import java.util.Observer;
/**
* Created by maiyu on 2017/6/18.
* 觀察者
*/
public class SimpleObserver implements Observer {
/**
* 初始化,爲被觀察者添加觀察者對象
* @param observable
*/
public SimpleObserver(SimpleObservable observable){
observable.addObserver(this);
}
/**
* 當被觀察者的數據改變時,觸發此方法
* @param o
* @param object
*/
@Override
public void update(Observable o, Object object) {
//強制轉換爲SimpleObservable類,並執行它的getData()方法
System.out.println("data is changed: " + ((SimpleObservable)o).getData());
}
(3)測試類:
public class Test {
public static void main(String[] args)throws Exception{
//創建被觀察者對象
SimpleObservable observable = new SimpleObservable();
//創建觀察者對象,把被觀察者當做參數
SimpleObserver observer = new SimpleObserver(observable);
observable.setData(1);
observable.setData(2);
//此處,因爲狀態還是2,沒有改變,不會通知
observable.setData(2);
observable.setData(3);
}
}
輸出結果:
data is changed: 1
data is changed: 2
data is changed: 3
只有在狀態改變時才通知,不改變不通知三,RxAndroid:
在Android編程時,經常會使用後臺線程,那麼就可以使用這種方式,目前的異步編程方式會導致一些問題,如:
(1).異步任務容易導致內存泄漏
(2)CursorLoaders和ContentProvider的使用經常需要大量的配置數字模板
(3)後臺服務長時間運行在後臺,不能很快結束操作,會浪費資源
(4)訪問網絡接口調用返回數據,尤其在使用回調時候,處理數據很麻煩
1.創建觀察者
在異步模型中創建觀察者:
(1)定義一個方法,它完成某些任務,然後從異步調用中返回一個值,這個方法是觀察者的一部分
(2)將這個異步調用本身定義爲一個Observable
(3)觀察者通過訂閱(Subscribe)操作關聯到哪個Observable
(4)繼續你的業務邏輯,等方法返回時,Observable會發射結果,觀察者的方法會開始處理結果或者結果集
2.觀察者回調方法:onNext, onError , onComplete
(1)onNext(T item):Observable調用這個方法發射數據,方法的參數就是Observable發射的數據,這個方法可能會被多次調用,取決於我們的實現
(2)onError(Exception ex)
當Observable遇到錯誤或者無法返回期望的數據時會調用這個方法,這個調用會終止Observable,後續不會再調用onNext和onCompleted,
onError方法的參數就是拋出的異常
(3)onComplete
正常終止,如果沒有遇到錯誤,Observable在最後一次調用onNext之後調用此方法
3.創建操作Create:
(1)使用一個函數從頭開始參加一個Observable:
Create{onNext ; onNext ; onComplete}
注意:可在傳遞給create方法的函數中檢查觀察者的isUnsubscribed狀態,以便在沒有觀察者的時候,讓你的Observable停止發射數據或做昂貴的運算。
4.例子如下:
創建類:RxUtils,用於存放後面沒種實現方式的方法
public class RxUtils {
private static final String TAG = RxUtils.class.getSimpleName();
<1>第一例子:使用Observable.create()方法來創建:
(1)創建Observable對象,在create方法裏面傳入參數new Observable.OnSubscribe()對象,
然後利用onNext設置信息,最後調用onComplete()方法,如下:
//使用Observable.create方法來創建
Observable<String > observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello");
subscriber.onNext("good");
subscriber.onNext(downLoadJson());
subscriber.onNext("約嗎");
//調用onCompleted()方法來完成
subscriber.onCompleted();
}
});
(2)創建Subscriber對象,重寫onError,onComplete,onNext方法:
代碼如下:
//創建Subscriber對象,這裏傳入字符串類型,因爲什麼我們是發送字符串
Subscriber<String> showsub = new Subscriber<String>() {
@Override
public void onCompleted() {
Log.i(TAG , "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i(TAG , "onError:"+ e.toString());
}
@Override
public void onNext(String s) {
Log.i(TAG , "onNext: " + s);
}
};
/**
* 定義下載方法
* @return
*/
private static String downLoadJson() {
return "json_data";
}
(3)調用Observable對象的subscribe關聯Subscriber對象:
/**
* 關聯被觀察者
*/
observable.subscribe(showsub);
(4)在Activity中爲某個按鈕設置監聽:
public void btnOnClick(View view){
RxUtils.createObservable();
}
(5)輸出結果如下:
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: hello
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: good
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: json_data
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: 約嗎
06-20 01:30:46.313 6162-6162/? I/RxUtils: onCompleted
<2>第二種方法:也是利用create方法,只是不用創建Observable和Subscriber對象,而是直接實現,如下:打印整數1到10
public static void createObservable2(){
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
//如果沒有解除關聯
if(!subscriber.isUnsubscribed()){
for(int i = 0 ; i < 10 ; i++){
subscriber.onNext(i);
}
subscriber.onCompleted();
}
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.i(TAG , "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i(TAG , "e: " + e.toString());
}
@Override
public void onNext(Integer integer) {
Log.i(TAG , "onNext: " +integer);
}
});
}
Activity中按鈕監聽:
public void btnOnClick2(View view){
RxUtils.createObservable2();
}
輸出結果:
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 0
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 1
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 2
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 3
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 4
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 5
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 6
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 7
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 8
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 9
06-20 01:36:37.593 6162-6162/? I/RxUtils: onCompleted
<3>第3種方法:from()方法,定義數組
/**
* Observable.from()方法
* 使用在被觀察者,返回的一般都是數據類型
*/
public static void from(){
Integer[] items = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
Observable observable = Observable.from(items);
observable.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.i(TAG , o.toString());
}
});
}
輸出:
06-20 02:01:43.081 6162-6162/? I/RxUtils: 1
06-20 02:01:43.081 6162-6162/? I/RxUtils: 2
06-20 02:01:43.081 6162-6162/? I/RxUtils: 3
06-20 02:01:43.081 6162-6162/? I/RxUtils: 4
06-20 02:01:43.081 6162-6162/? I/RxUtils: 5
06-20 02:01:43.081 6162-6162/? I/RxUtils: 6
06-20 02:01:43.081 6162-6162/? I/RxUtils: 7
06-20 02:01:43.081 6162-6162/? I/RxUtils: 8
06-20 02:01:43.081 6162-6162/? I/RxUtils: 9
--------- beginning of /dev/log/system
<4>第4種:Interval指定時間間隔發送數據:
/**
* interval指定某一時刻進行數據發送:定時器
*/
public static void interval(){
//每隔1秒發送一次數據
Observable observable = Observable.interval(1 , 1 , TimeUnit.SECONDS);
observable.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.i(TAG , o.toString());
}
});
}
輸出結果:發現每隔1秒,後臺就打印一個數據,,截取部分如下:
06-20 02:04:28.997 25326-25438/? I/RxUtils: 0
06-20 02:04:29.997 25326-25438/? I/RxUtils: 1
06-20 02:04:30.997 25326-25438/? I/RxUtils: 2
06-20 02:04:32.001 25326-25438/? I/RxUtils: 3
06-20 02:04:32.997 25326-25438/? I/RxUtils: 4
...
<5>第5種:just來實現範圍數據,參數爲多個數組對象,如:
/**
* 範圍數據:如下面依次輸出兩個數組的元素
*/
public static void just(){
//定義兩個數組
Integer[] items1 = {1 , 3 , 5 , 7 , 9};
Integer[] items2 = {2 , 4 , 6 , 8 , 10};
//調用Observable.just(數組1,數組2,.....數組10);
Observable observable = Observable.just(items1 , items2);
//在這裏設置Subscriber的類型爲Integer[]:對應上面的Integer類型的數組
observable.subscribe(new Subscriber<Integer[]>() {
@Override
public void onCompleted() {
Log.i(TAG , "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i(TAG , "onError: " + e.getMessage());
}
@Override
public void onNext(Integer[] o) {
for(Integer i : o)
Log.d(TAG , "onNext : " +i);
}
});
}
輸出結果:依次輸出兩個數組的數據
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 1
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 3
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 5
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 7
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 9
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 2
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 4
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 6
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 8
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 10
06-20 02:07:00.337 25643-25643/? I/RxUtils: onCompleted
<6>第6種:利用range來實現從指定初始位置和個數的範圍,如:
/**
* range方法:定義開始下標與個數
*/
public static void range(){
//利用Observable.range(開始下標,個數);
Observable observable = Observable.range(3 , 5);
//傳入Action1的參數類型Integer
observable.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG , "call : " + integer);
}
});
}
輸出結果:
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 3
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 4
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 5
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 6
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 7
--------- beginning of /dev/log/system
<7>第7種:利用filter來實現某些過濾信息:
/**
* Observable.filter()方法:用於過濾某些東東
*/
public static void filter(){
//創建一個數組
Integer[] items = {1 , 2 , 3 , 4 , 5 , 6};
//調用from添加
Observable observable = Observable.from(items);
//添加過濾器,傳入<Integer,Boolean>參數:過濾小於等於3的數字
observable.filter(new Func1<Integer , Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer > 3;
}
})
//設置訂閱者是如何執行的:Schedulers.io---通過網絡獲取數據
.observeOn(Schedulers.io())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.d(TAG , "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.d(TAG , "onError : " + e.getMessage());
}
@Override
public void onNext(Integer integer) {
Log.d(TAG , "onNext : " + integer);
}
});
}
結果如下:
06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 4
06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 5
06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 6
06-20 02:13:52.561 26628-26661/? D/RxUtils: onCompleted
四,RxAndroid應用場景
1.替代AsyncTask完成下載操作
2.結合OkHttp完成網絡訪問操作、包括下載文件、提交form表單數據
3.結合ListView、GridView使用完成對圖文混排操作
4.結合OkHttp網絡訪問框架使用
5.RxAndroid編程思路的總結
1.替代AsyncTask完成下載操作:如下載一直圖片
(1)在Activity中:
* 在實際開發中Activity充當的角色太多了:
* 1.UI主線程負責繪製UI
* 2.開啓子線程獲取網絡數據
* 3.賦值到控件中
* 4.判斷邏輯等等
而下載圖片常用方法:
/**
* 下載張圖片:
* 1.AsyncTask
* 2.Handler機制
* 3.發現有更好的即觀察者模式
*/
如第1種:那麼必須創建類繼承AsyncTask<String , 參數,byte[]>等
或者自己封裝:
public class DownLoadUtils {
/**
* 傳統模式,
*
* @param path
* @return
*/
public static byte[] downloadImg(String path, CallBack callBack) {
//在這裏定義異步任務
return null;
}
interface CallBack {
void callback(byte[] data);
}
}
但是發現這些太繁瑣或是消耗資源多,於是採用第3種:
(2)創建工具類:
主要有如下幾個知識點:
------定義並在構造方法裏創建OkHttpClient
記得在build.gradle添加OkhttpClient的依賴
compile 'com.squareup.okhttp:okhttp:2.7.2'
------使用Observable創建下載方法,參數爲path,public class DownLoadUtils {
//定義OkHttpClient
private OkHttpClient okHttpClient ;
/**
* 構造函數:實例化OkHttpClient對象
*/
public DownLoadUtils(){
okHttpClient = new OkHttpClient();
}
/**
* 創建觀察者模式的下載方法,這裏
* @param path -----傳入地址參數
* @return ------返回btye[]數組
*/
public Observable<byte[]> downloadImg(final String path){
//使用create()方法
return Observable.create(new Observable.OnSubscribe<byte[]>() {
@Override
public void call(final Subscriber<? super byte[]> subscriber) {
//判斷是否已經綁定訂閱
if(!subscriber.isUnsubscribed()){
//使用OkhttpClient訪問網絡步驟
//創建Request對象,調用.url()傳入地址,build()完成
Request request = new Request.Builder().url(path).build();
//調用okttpClient.newCall(Request對象).enqueue()執行異步get請求
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
//執行subscriber.onError()方法
subscriber.onError(e);
}
/**
* 請求成功
* @param response
* @throws IOException
*/
@Override
public void onResponse(Response response) throws IOException {
//判斷返回結果是否成功
if(response.isSuccessful()){
//獲取返回的byte[]數組
byte[] data = response.body().bytes();
//判空
if(data != null){
//發射數據
subscriber.onNext(data);
}
}
//完成
subscriber.onCompleted();
}
});
}
}
});
}
}
在Activity中:
初始化DownLoad類:
utils = new DownLoadUtils();
爲按鈕設置監聽,在監聽裏面執行代碼如下:
//下載圖片------設置訂閱執行方式(通過網絡獲取數據)-----設置主線程顯示
utils.downloadImg(imgPath).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<byte[]>() {
@Override
public void onCompleted() {
Log.i(TAG , "onCompleted");//對話框取消
}
@Override
public void onError(Throwable e) {
Log.i(TAG , "onError: " + e);
}
@Override
public void onNext(byte[] bytes) {
//顯示圖片,這裏沒有對圖片進行壓縮等處理
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0 , bytes.length);
mImg.setImageBitmap(bitmap);
}
});
結果:顯示一張圖片:
如傳入地址:
private String imgPath = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497953788142&di=370d893f7390ea12dc770083b171c1f2&imgtype=0&src=http%3A%2F%2Fxke8.com%2Fuploads%2Fallimg%2Fc150921%2F1442O51G4A0-1I13.jpg";
有點長,不過結果辣眼睛,瞬間秒殺你的睏意:
2.利用OkhtttpClient實現用戶登錄:
主要代碼如下:
工具類:
/**
* Created by maiyu on 2017/6/20.
* 登錄類
*/
public class LoginUtils {
//定義OkHttpClent對象
private OkHttpClient okHttpClient ;
public LoginUtils(){
okHttpClient = new OkHttpClient();
}
/**
* 登錄實現
* @param url
* @param params
* @return String
*/
public Observable<String> login(final String url , final Map<String , String> params){
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(final Subscriber<? super String> subscriber) {
//判斷是否已經綁定
if(!subscriber.isUnsubscribed()){
//創建FormEncodingBuilder對象
FormEncodingBuilder builder = new FormEncodingBuilder();
//添加參數
if(params != null && !params.isEmpty()){
for(Map.Entry<String , String> entry : params.entrySet()){
builder.add(entry.getKey() , entry.getValue());
}
}
//創建RequestBody對象
RequestBody body = builder.build();
//創建Request對象
Request request = new Request.Builder().url(url).post(body).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
subscriber.onError(e);
}
@Override
public void onResponse(Response response) throws IOException {
if(response.isSuccessful()){
//訂閱
subscriber.onNext(response.body().string());
}
subscriber.onCompleted();
}
});
}
}
});
}
}
登錄按鈕監聽實現:
public void toLogin(){
Map<String , String> params = new HashMap<String , String>();
params.put("username" , "獲取用戶名");
params.put("password" , "獲取密碼");
loginUtils.login(loginUrl , params).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Log.i(TAG , "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i(TAG , "onError : " + e);
}
@Override
public void onNext(String s) {
//跳轉...
Intent intent = new Intent();
startActivity(intent);
}
});
}
附註代碼下載地址:代碼下載地址