原文鏈接 http://blog.csdn.net/theone10211024/article/details/50435325
一、Scheduler線程切換
這種場景經常會在“后臺線程取數據,主線程展示”的模式中看見
[html]view plaincopy
Observable.just(1,?2,?3,?4)
.subscribeOn(Schedulers.io())?//?指定?subscribe()?發生在?IO?線程
.observeOn(AndroidSchedulers.mainThread())?//?指定?Subscriber?的回調發生在主線程
.subscribe(new?Action1()?{
@Override
public?void?call(Integer?number)?{
Log.d(tag,?"number:"?+?number);
}
});
二、使用debounce做textSearch
用簡單的話講就是當N個結點發生的時間太靠近(即發生的時間差小于設定的值T),debounce就會自動過濾掉前N-1個結點。
比如在做百度地址聯想的時候,可以使用debounce減少頻繁的網絡請求。避免每輸入(刪除)一個字就做一次聯想
[html]view plaincopy
RxTextView.textChangeEvents(inputEditText)
.debounce(400,?TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d("onComplete");
}
@Override
public?void?onError(Throwable?e)?{
log.d("Error");
}
@Override
public?void?onNext(TextViewTextChangeEvent?onTextChangeEvent)?{
log.d(format("Searching?for?%s",?onTextChangeEvent.text().toString()));
}
});
三、Retrofit結合RxJava做網絡請求框架
這里不作詳解,具體的介紹可以看扔物線的這篇文章,對RxJava的入門者有很大的啟發。其中也講到了RxJava和Retrofit如何結合來實現更簡潔的代碼
四、RxJava代替EventBus進行數據傳遞:RxBus
注意:RxBus并不是一個庫,而是一種模式,是使用了RxJava的思想來達到EventBus的數據傳遞效果。這篇文章把RxBus講的比較詳細。
例如:注冊的時候所有輸入信息(郵箱、密碼、電話號碼等)合法才點亮注冊按鈕。
[html]view plaincopy
Observable_emailChangeObservable=RxTextView.textChanges(_email).skip(1);
Observable_passwordChangeObservable=RxTextView.textChanges(_password).skip(1);
Observable_numberChangeObservable=RxTextView.textChanges(_number).skip(1);
Observable.combineLatest(_emailChangeObservable,
_passwordChangeObservable,
_numberChangeObservable,
new?Func3()?{
@Override
public?Boolean?call(CharSequence?newEmail,
CharSequence?newPassword,
CharSequence?newNumber)?{
Log.d("xiayong",newEmail+"?"+newPassword+"?"+newNumber);
booleanemailValid=?!isEmpty(newEmail)?&&
EMAIL_ADDRESS.matcher(newEmail).matches();
if?(!emailValid)?{
_email.setError("Invalid?Email!");
}
booleanpassValid=?!isEmpty(newPassword)?&&?newPassword.length()>8;
if?(!passValid)?{
_password.setError("Invalid?Password!");
}
booleannumValid=?!isEmpty(newNumber);
if?(numValid)?{
intnum=Integer.parseInt(newNumber.toString());
numValid=num>0?&&?num<=?100;
}
if?(!numValid)?{
_number.setError("Invalid?Number!");
}
return?emailValid?&&?passValid?&&?numValid;
}
})//
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.d("Error");
}
@Override
public?void?onNext(Boolean?formValid)?{
_btnValidIndicator.setEnabled(formValid);
}
});
六、使用merge合并兩個數據源。
例如一組數據來自網絡,一組數據來自文件,需要合并兩組數據一起展示。
[html]view plaincopy
Observable.merge(getDataFromFile(),?getDataFromNet())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new?Subscriber()?{
@Override
public?void?onCompleted()?{
log.d("done?loading?all?data");
}
@Override
public?void?onError(Throwable?e)?{
log.d("error");
}
@Override
public?void?onNext(String?data)?{
log.d("all?merged?data?will?pass?here?one?by?one!")
});
七、使用concat和first做緩存
依次檢查memory、disk和network中是否存在數據,任何一步一旦發現數據后面的操作都不執行。
[html]view plaincopy
Observablememory=Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(Subscribersubscriber)?{
if?(memoryCache?!=?null)?{
subscriber.onNext(memoryCache);
}?else?{
subscriber.onCompleted();
}
}
});
Observabledisk=Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(Subscribersubscriber)?{
StringcachePref=rxPreferences.getString("cache").get();
if?(!TextUtils.isEmpty(cachePref))?{
subscriber.onNext(cachePref);
}?else?{
subscriber.onCompleted();
}
}
});
Observablenetwork=Observable.just("network");
//依次檢查memory、disk、network
Observable.concat(memory,?disk,?network)
.first()
.subscribeOn(Schedulers.newThread())
.subscribe(s?->{
memoryCache="memory";
System.out.println("--------------subscribe:?"?+?s);
});
八、使用timer做定時操作。當有“x秒后執行y操作”類似的需求的時候,想到使用timer
例如:2秒后輸出日志“hello world”,然后結束。
[html]view plaincopy
Observable.timer(2,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Long?number)?{
log.d?("hello?world");
}
});
九、使用interval做周期性操作。當有“每隔xx秒后執行yy操作”類似的需求的時候,想到使用interval
例如:每隔2秒輸出日志“helloworld”。
[html]view plaincopy
Observable.interval(2,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Long?number)?{
log.d?("hello?world");
}
});
十、使用throttleFirst防止按鈕重復點擊
ps:debounce也能達到同樣的效果
[html]view plaincopy
RxView.clicks(button)
.throttleFirst(1,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Object?o)?{
log.d("button?clicked");
}
});
十一、使用schedulePeriodically做輪詢請求
[html]view plaincopy
Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(final?Subscriberobserver)?{
Schedulers.newThread().createWorker()
.schedulePeriodically(new?Action0()?{
@Override
public?void?call()?{
observer.onNext(doNetworkCallAndGetStringResult());
}
},?INITIAL_DELAY,?POLLING_INTERVAL,?TimeUnit.MILLISECONDS);
}
}).subscribe(new?Action1()?{
@Override
public?void?call(String?s)?{
log.d("polling….”));
}
})
十二、RxJava進行數組、list的遍歷
[html]view plaincopy
String[]names=?{"Tom",?"Lily",?"Alisa",?"Sheldon",?"Bill"};
Observable
.from(names)
.subscribe(new?Action1()?{
@Override
public?void?call(String?name)?{
log.d(name);
}
});
十三、解決嵌套回調(callback hell)問題
[html]view plaincopy
NetworkService.getToken("username",?"password")
.flatMap(s?->NetworkService.getMessage(s))
.subscribe(s?->{
System.out.println("message:?"?+?s);
})
十四、響應式的界面
比如勾選了某個checkbox,自動更新對應的preference
[html]view plaincopy
SharedPreferencespreferences=PreferenceManager.getDefaultSharedPreferences(this);
RxSharedPreferencesrxPreferences=RxSharedPreferences.create(preferences);
Preferencechecked=rxPreferences.getBoolean("checked",?true);
CheckBoxcheckBox=?(CheckBox)?findViewById(R.id.cb_test);
RxCompoundButton.checkedChanges(checkBox)
.subscribe(checked.asAction());
最后,由于個人能力有限,文章難免有疏漏之處,如果您有任何疑議,請讓我知道,謝謝!本文所有的例子已經上傳到github上