android——rxjava的使用(连续多个弹窗的处理)

2024-05-28 1206阅读

温馨提示:这篇文章已超过372天没有更新,请注意相关的内容是否还可用!

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

android——rxjava的使用(连续多个弹窗的处理)
(图片来源网络,侵删)

文章目录

  • 前言
  • 一、rxjava是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.读入数据
  • 总结

    前言

    本文介绍项目开发中使用到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 {
                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 {
            return Observable.create { 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 {
            return Observable.create { 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 {
            return Observable.create { 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库,它用于实现异步编程和流式处理,通过将事件和数据流以数据序列的形式进行处理,提高了代码的可读性和可维护性。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]