一:核心思想
- RxJava1.0和RxJava2.0的核心思想都是观察者模式,只不过RxJava2.0在RxJava1.0的基础对一些方法进行了优化,方便于开发者更好地理解其编程思想,同时又增加了一部分新的方法解决1.0存在的问题,例如背压等
- 被观察的对象发生变化时,自动将变动的消息发给观察者。因为主用的是Kotlin,而且不同喜欢java的风格,所以对RXjava比较抵触,但这位作者写的实在是太好啦,就改成kotlin了。
作者:肖邦kaka
链接:https://www.jianshu.com/p/cd3557b1a474
来源:简书 - 添加依赖
implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
二:简单观察者模式Demo一:Emitter发送与Observe接口回调
package com.ywjh.rxjavasample
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.ObservableOnSubscribe
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
class MainActivity : AppCompatActivity() {
private val TAG = "RxJavaTag"
private var mDisposable: Disposable? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rxJavaBaseUse()
}
private fun rxJavaBaseUse() {
val obs: Observable<String> = Observable.create(object : ObservableOnSubscribe<String> {
@Throws(Exception::class)
override fun subscribe(emitter: ObservableEmitter<String?>) {
emitter.onNext("连载1")
emitter.onNext("连载2")
emitter.onNext("连载3")
emitter.onComplete()
}
})
val observer: Observer<String?> = object : Observer<String?> {
override fun onNext(value: String?) {
if ("2" == value) {
mDisposable?.dispose()
return
}
Log.e(TAG,"onNext:"+value);
}
override fun onSubscribe(d: Disposable?) {
mDisposable = d
Log.e(TAG,"onSubscribe");
}
override fun onError(e: Throwable?) {
if (e != null) {
Log.e(TAG,"onError="+e.message)
};
}
override fun onComplete() {
Log.e(TAG,"onComplete()");
}
}
obs.subscribe(observer)
}
}
三:使用Scheduler调度线程,RXjava最常用写法:异步+链式编程【Demo二:修改为异步+链式】
- RxJava遵循哪个线程产生就在哪个线程消费的原则,也就是说线程不会产生变化,始终在同一个。然后我们一般使用RxJava都是后台执行,前台调用。
1)本着这个原则,我们需要调用observeOn(AndroidSchedulers.mainThread()),observeOn是事件回调的线程,AndroidSchedulers.mainThread()一看就知道是主线程,
2)subscribeOn(Schedulers.io()),subscribeOn是事件执行的线程,Schedulers.io()是子线程,这里也可以用Schedulers.newThread(),只不过io线程可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。
3)链式-一连串逻辑从头写到尾
private fun rxJavaChainUse() {
Observable.create<String> { emitter ->
emitter.onNext("连载1")
emitter.onNext("连载2")
emitter.onNext("连载3")
emitter.onComplete()
}
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(object : Observer<String> {
override fun onSubscribe(d: Disposable) {
Log.e(TAG, "onSubscribe")
}
override fun onNext(value: String) {
Log.e(TAG, "onNext:$value")
}
override fun onError(e: Throwable) {
Log.e(TAG, "onError=" + e.message)
}
override fun onComplete() {
Log.e(TAG, "onComplete()")
}
})
}
四:更多应用场景
- 与Retrofit联用
Retrofit+RxJava的上网模式已经非常火了,如果有不了解的可以看笔者的这篇文章https://www.jianshu.com/writer#/notebooks/5118090/notes/25405151 - Rxpermissions等类库的使用
基于RxJava的开源类库Rxpermissions、RxBinding以及RxBus在很多项目中已经非常常见,并且被证明了是极其好用的。 - 所有用到异步的地方
因为RxJava就是一个支持异步的链式编程,所以所有的用到异步的地方,我们都可以用RxJava来完成
异步例一:
1)干嘛不直接new Handler().postDelayed()。如果你的程序线程里面做的操作很简单,那么你用new Handler().postDelayed()无所谓,但是如果你的操作很复杂,那么这时候就体现出了RxJava的好处了,借用扔物线大神的一句话就是"随着程序逻辑变得越来越复杂,RxJava依然能够保持简洁"。
private fun timeDoSomething() {
Observable.create<Int> { emitter ->
emitter.onNext(123)
sleep(3000)
emitter.onNext(456)
}.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(object : Consumer<Int?> {
override fun accept(t: Int?) {
Log.e(TAG, t.toString() + "")
}
}, object : Consumer<Throwable?> {
@Throws(java.lang.Exception::class)
override fun accept(throwable: Throwable?) {
}
}, object : Action {
@Throws(java.lang.Exception::class)
override fun run() {
}
})
}
- 异步例二:
1)下面来说一个复杂的操作,比如我们要依次加载10张图片(加载图片是耗时过程),其中第六张我们延时3秒加载,第7张我们复制到sd卡里,第8张我们要上网络,那么请问你要怎么做,如果用Handler,必然是各种嵌套,各种逻辑复杂得让你再看一眼都难受,但是如果使用RxJava呢?
private fun complicatedDoSomething(drawableRes: IntArray) {
Observable.create<Drawable> { emitter ->
for (i in drawableRes.indices) {
val drawable = resources.getDrawable(drawableRes[i])
if (i == 5) {
sleep(3000)
}
if (i == 6) {
val bitmap = (drawable as BitmapDrawable).bitmap
saveBitmap(bitmap, "test.png", CompressFormat.PNG)
}
if (i == 7) {
updateIcon(drawable)
}
emitter.onNext(drawable)
}
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Consumer<Drawable?> {
@Throws(java.lang.Exception::class)
override fun accept(drawable: Drawable?) {
}
})
}
private fun updateIcon(drawable: Drawable) {}
fun saveBitmap(bitmap: Bitmap, name: String?, format: CompressFormat?) {
val file = File(Environment.getExternalStorageDirectory(),
name)
var out: FileOutputStream? = null
try {
out = FileOutputStream(file)
bitmap.compress(format, 100,
out)
out.close()
} catch (e: IOException) {
e.printStackTrace()
}
}