android——rxjava的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文介绍项目开发中使用到rxjava的情形,以及详细的代码。


一、rxjava是什么?

RxJava是一个基于事件流实现异步操作的框架,其作用是实现异步操作,类似于Android中的AsyncTask。它是在Java虚拟机(JVM)上使用可观测的序列来构建异步的、基于事件的程序。RxJava结合了观察者模式,迭代器模式和函数式的精华,最早由Netflix公司用于减少REST调用次数,后迁移到Java平台,并得到了广泛的应用。

RxJava的一些主要特点包括支持Java 8 Lambda表达式,支持异步和同步编程,具有单一依赖关系,以及简洁、优雅的代码风格。此外,RxJava还解决了“回调地狱”问题,异步处理不再需要回调一层套一层,而是用链式调用的方式完成不同线程的回调。

对于Android开发者来说,RxJava在开发过程中常与RxAndroid一同使用,RxAndroid是针对RxJava在Android平台上使用的响应式扩展组件。然而,尽管RxJava带来了编程上的便利,但其复杂性也使得一些开发者对其持有保留态度。

二、使用步骤

1.引入库

代码如下(示例):

implementation 'io.reactivex.rxjava2:rxjava:2.2.21'

2.rxjava复杂的异步处理

需求:刚进入页面就进行连接(异步返回结果:失败、成功、连接中),点击按钮的时候,有几种状态: 1、连接失败--重新开始连接

        1.1 连接成功 --调阅读的方法

        1.2 连接失败 --UI进行提示失败

2、连接中

         2.1 连接成功 --调阅读的方法

        2.2 连接失败 --UI进行提示失败

3、连接成功 --调阅读的方法
 

实现方式一
class MainActivity : AppCompatActivity() {
    private val subHandle = SubHandle()
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
        subHandle.mConsumer = null
        subHandle.connect().subscribe()
    }
 
    fun btRead(view: View) {
        subHandle.handleStatus {
            subHandle.read()
        }
    }
 
    /**
     * 刚进入页面就进行连接,点击按钮的时候,有几种状态:
     * 1、连接失败--重新开始连接,
     *      1.1 连接成功 --调阅读的方法
     *      1.2 连接失败 --UI进行提示失败
     * 2、连接中
     *      2.1 连接成功 --调阅读的方法
     *      2.2 连接失败 --UI进行提示失败
     * 3、连接成功 --调阅读的方法
     */
    class SubHandle {
        var mConsumer: ((Int) -> Unit)? = null
        private var status = AtomicInteger(-1) // 0连接失败 1正在连接中 2连接成功
        private var disposable: Disposable? = null
 
        fun connect(): Observable<Int> {
            status.set(1)
            Log.e("TAG", "=连接=")
            return Observable.interval(5, TimeUnit.SECONDS)
                .take(1)
                .map {
                    val random = Random(System.currentTimeMillis())
                    val randomNumber = random.nextInt(3) // 生成一个0到2之间的随机整数
                    Log.e("TAG", "==funA输出$randomNumber")
                    randomNumber
                }
                .subscribeOn(Schedulers.io())
                .doOnNext {
                    if (it == 2) {
                        status.set(2)
                        mConsumer?.invoke(status.get())
                    } else {
                        status.set(0)
                        Log.e("TAG", "连接阅读器失败,给UI提示")
                    }
                }
        }
 
        fun handleStatus(consumer: (Int) -> Unit) {
            mConsumer = consumer
            when (status.get()) {
                0 -> {
                    Log.e("TAG", "连接失败过,正重试连接")
                    disposable?.dispose()
                    disposable = connect().subscribe()
                }
                1 -> Log.e("TAG", "正在连接")
                2 -> mConsumer?.invoke(status.get())
            }
        }
 
        fun read() {
            Log.e("TAG", "开始阅读")
        }
    }
}
实现方式二
class MainActivity : AppCompatActivity() {
    private var canRead = false
    private var connectStatus = 0 //1 代表 SUCC, 2 代表 FAIL, 0 代表 CONNECTING

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

    private fun connect() {
        Log.e("TAG", "=连接=")
        Thread(Runnable {
            Thread.sleep(5000) // 休眠5秒钟

            Observable.just(randomStatus())
                .doOnNext { connectStatus = it }
                .filter {
                    Log.e("TAG", "it状态" + it)
                    it == 1 && canRead
                }
                .subscribeOn(Schedulers.io())
                .doOnNext { read() }
                .subscribe()

        }).start()

    }

    fun btRead(view: View) {
        canRead = true
        Log.e("TAG", "点击按钮" + connectStatus)
        when (connectStatus) {
            1 -> read() //  1 代表 SUCC
            2 -> connect() //  2 代表 FAIL
            else -> {}
        }
    }

    private fun read() {
        Log.e("TAG", "开始阅读")
    }

    private fun randomStatus(): Int {
        val random = Random(System.currentTimeMillis())
        return random.nextInt(3)  //生成一个0到2之间的随机整数
    }
}

3、连续多个弹窗的处理

使用rxjava实现:

class MainActivity : AppCompatActivity() {
    private val compositeDisposable = CompositeDisposable()

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

    }

    @SuppressLint("CheckResult")
    fun btRead(view: View) {
        Log.e("TAG", "jjjjjj")
        showFirstDialog()
            .flatMap { showSecondDialog() }
            .flatMap { showThirdDialog() }.subscribe({
                Log.e("TAG", "3个弹窗都选了确定")
            }, { error ->
                Log.e("TAG", "点击了取消$error")
            })
    }

    private fun showFirstDialog(): Observable<Unit> {
        return Observable.create<Unit> { emitter ->
            val dialog = AlertDialog.Builder(this)
                .setMessage("第一个弹窗")
                .setPositiveButton("确定") { _, _ ->
                    emitter.onNext(Unit) // 发送事件,表示点击了确定按钮
                }
                .setNegativeButton("取消") { _, _ ->
                    emitter.onError(Throwable("1取消")) // 发送错误事件,表示点击了取消按钮
                }
                .setOnCancelListener {
                    emitter.onError(Throwable("1取消")) // 发送错误事件,表示点击了返回键
                }
                .create()
            dialog.show()
            emitter.setCancellable { dialog.dismiss() } // 在取消订阅时关闭弹窗
        }
    }

    private fun showSecondDialog(): Observable<Unit> {
        return Observable.create<Unit> { emitter ->
            val dialog = AlertDialog.Builder(this)
                .setMessage("第二个弹窗")
                .setPositiveButton("确定") { _, _ ->
                    emitter.onNext(Unit)
                }
                .setNegativeButton("取消") { _, _ ->
                    emitter.onError(Throwable("2取消"))
                }
                .setOnCancelListener {
                    emitter.onError(Throwable("2取消"))
                }
                .create()
            dialog.show()
            emitter.setCancellable { dialog.dismiss() }
        }
    }

    private fun showThirdDialog(): Observable<Unit> {
        return Observable.create<Unit> { emitter ->
            val dialog = AlertDialog.Builder(this)
                .setMessage("第三个弹窗")
                .setPositiveButton("确定") { _, _ ->
                    emitter.onNext(Unit)
                }
                .setNegativeButton("取消") { _, _ ->
                    emitter.onError(Throwable("3取消"))
                }
                .setOnCancelListener {
                    emitter.onError(Throwable("3取消"))
                }
                .create()
            dialog.show()
            emitter.setCancellable { dialog.dismiss() }
        }
    }

}

协程实现:

fun btRead(view: View) {
        lifecycleScope.launch {
            try {
                showAlertDialog(this@MainActivity, "提示1", "第一个弹窗")
                showAlertDialog(this@MainActivity, "提示1", "第二个弹窗")
                showAlertDialog(this@MainActivity, "提示1", "第三个弹窗")
            } catch (e: Exception) {
                Log.e("showAlertDialog", "2222111发生异常")
            }
        }
    }

    private suspend fun showAlertDialog(context: Context, title: String, message: String): Boolean =
        suspendCancellableCoroutine { ctn ->
            val activityRef = WeakReference(context as MainActivity)
            val alertDialog = AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("确定") { dialog, _ ->
                    // 点击确定按钮的逻辑处理
                    dialog.dismiss()
                    activityRef.get()?.let {
                        ctn.resume(true) {}
                    }
                }
                .setNegativeButton("取消") { dialog, _ ->
                    // 点击取消按钮的逻辑处理
                    dialog.dismiss()
                    activityRef.get()?.let {
                        ctn.resumeWithException(Exception(message + "取消"))
                    }
                }
                .setOnCancelListener {
                    activityRef.get()?.let {
                        ctn.resumeWithException(Exception("蒙层取消"))
                    }
                }.create()
            alertDialog.show()
        }

总结

RxJava是一个基于Java语言的Reactive Extensions库,它用于实现异步编程和流式处理,通过将事件和数据流以数据序列的形式进行处理,提高了代码的可读性和可维护性。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android Repository是一种用于处理数据源的设计模式,在Android开发中广泛使用。它的主要目的是将数据源(例如数据库、网络请求等)与UI层分离开来,实现更好的代码组织和结构。使用Android Repository模式,我们可以将数据的获取、存储和管理逻辑从UI层分离出来,使得UI层只负责展示数据,而数据的获取和存储则由Repository负责。 RxJava是一种响应式编程库,它提供了一种优雅和强大的方式来处理异步事件流。通过使用Observable和Observer的概念,我们可以将事件流转换成链式的操作符来处理和组合数据。RxJava可以让我们更容易地进行异步编程,并且具有线程切换、错误处理、背压等优秀的特性。 LiveData是Android Jetpack组件中的一部分,用于解决UI数据和生命周期的关联问题。LiveData具有生命周期感知能力,当数据发生变化时,它会自动通知相关观察者进行更新。LiveData可以确保在合适的时间和生命周期下更新UI,避免了内存泄漏和空指针异常等问题。 使用RxJava和LiveData可以将数据源的异步操作与UI层分离开来。在Android开发中,我们经常需要进行异步操作,例如进行网络请求或数据库查询。使用RxJava可以让我们更方便地处理这些异步操作,在链式的操作符中进行数据的变换、过滤和组合等操作。 然后,利用LiveData可以将异步操作的结果通知给UI层。LiveData具有生命周期感知能力,当Activity或Fragment处于活跃状态时,LiveData会通知相关观察者进行数据更新,从而保证数据的正确显示。 综上所述,结合Android Repository、RxJava和LiveData可以实现一套完整的、优雅的异步操作和UI更新的方案。这些组件的结合使用可以提高开发效率,降低代码的复杂度,并且保证了数据的正确和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wy313622821

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值