【RXjava】从入土再入门

一:核心思想

  1. RxJava1.0和RxJava2.0的核心思想都是观察者模式,只不过RxJava2.0在RxJava1.0的基础对一些方法进行了优化,方便于开发者更好地理解其编程思想,同时又增加了一部分新的方法解决1.0存在的问题,例如背压等
  2. 被观察的对象发生变化时,自动将变动的消息发给观察者。因为主用的是Kotlin,而且不同喜欢java的风格,所以对RXjava比较抵触,但这位作者写的实在是太好啦,就改成kotlin了。
    作者:肖邦kaka
    链接:https://www.jianshu.com/p/cd3557b1a474
    来源:简书
  3. 添加依赖
    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
    //0. 对象解释Disposable英文意思是可随意使用的, 这里就相当于读者和连载小说的订阅关系,
    // 如果读者不想再订阅该小说了,可以调用 mDisposable.dispose()取消订阅,
    // 此时连载小说更新的时候就不会再推送给读者了

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        rxJavaBaseUse()
    }

    //RxJava基本使用
    private fun rxJavaBaseUse() {
    
    
        //被观察者
        //1. create方法生成对象,里面放的参数ObservableOnSubscribe<T>,可以理解为一个计划表
        val obs: Observable<String> = Observable.create(object : ObservableOnSubscribe<String> {
    
    
            @Throws(Exception::class)
            //2. 重写subscribe方法,里面写具体的计划,本文的例子就是推送连载1、连载2和连载3
            //onNext方法可以无限调用,Observer(观察者)所有的都能接收到,
            // onError和onComplete是互斥的,Observer(观察者)只能接收到一个,
            // OnComplete可以重复调用,但是Observer(观察者)只会接收一次,
            // onError不可以重复调用,第二次调用就会报异常

            override fun subscribe(emitter: ObservableEmitter<String?>) {
    
    //ObservableEmitter<String>对象的Emitter是发射器的意思
                emitter.onNext("连载1")
                emitter.onNext("连载2")
                emitter.onNext("连载3")
                emitter.onComplete()
            }
        })

        //观察者
        //1.通过匿名内部类创建接口对象,并实现其内部的方法一一对应接收
        val observer: Observer<String?> = object : Observer<String?> {
    
    

            override fun onNext(value: String?) {
    
    
                if ("2" == value) {
    
    
                    mDisposable?.dispose()//接受到消息为"2"取消订阅
                    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()");
            }
        }
        //2.建立订阅关系
        obs.subscribe(observer)
    }
}

三:使用Scheduler调度线程,RXjava最常用写法:异步+链式编程【Demo二:修改为异步+链式】

  1. RxJava遵循哪个线程产生就在哪个线程消费的原则,也就是说线程不会产生变化,始终在同一个。然后我们一般使用RxJava都是后台执行,前台调用。
    1)本着这个原则,我们需要调用observeOn(AndroidSchedulers.mainThread()),observeOn是事件回调的线程,AndroidSchedulers.mainThread()一看就知道是主线程,
    2)subscribeOn(Schedulers.io()),subscribeOn是事件执行的线程,Schedulers.io()是子线程,这里也可以用Schedulers.newThread(),只不过io线程可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。
    3)链式-一连串逻辑从头写到尾
//RxJava链式使用
    private fun rxJavaChainUse() {
    
    
        Observable.create<String> {
    
     emitter ->
            emitter.onNext("连载1")
            emitter.onNext("连载2")
            emitter.onNext("连载3")
            emitter.onComplete()
        }
                .observeOn(AndroidSchedulers.mainThread()) //回调在主线程
                .subscribeOn(Schedulers.io()) //执行在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()")
                    }
                })
    }

四:更多应用场景

  1. 与Retrofit联用
    Retrofit+RxJava的上网模式已经非常火了,如果有不了解的可以看笔者的这篇文章https://www.jianshu.com/writer#/notebooks/5118090/notes/25405151
  2. Rxpermissions等类库的使用
    基于RxJava的开源类库Rxpermissions、RxBinding以及RxBus在很多项目中已经非常常见,并且被证明了是极其好用的。
  3. 所有用到异步的地方
    因为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. 异步例二:
    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])
                //第6个图片延时3秒后架子
                if (i == 5) {
    
    
                    sleep(3000)
                }
                //复制第7张图片到sd卡
                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?) {
    
    
                        //回调后在UI界面上展示出来
                    }
                })
    }

    private fun updateIcon(drawable: Drawable) {
    
    }


    /**
     * 将Bitmap以指定格式保存到指定路径
     * @param bitmap
     * @param name
     */
    fun saveBitmap(bitmap: Bitmap, name: String?, format: CompressFormat?) {
    
    
        // 创建一个位于SD卡上的文件
        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()
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_38304672/article/details/112977910
今日推荐