rxjava+LiveData VS 协程+flow, +Retrofit+Okhttp3,两种方案的不同使用.

1.前提

作者最近在学习kotlin,刚看到协程,又看到了flow.发现这两个东西是可以完成取代rxjava和LiveData的。然后我就来找不同,一起体验一下两种东西加在一起的不同. 当然了,如果你使用的是JAVA,就老老实实用RXJAVA+LiveData把。 协程是Android里面kotlin特有的。

在这里插入图片描述

2.对比

是骡子是马,拉出来遛一遛,咋们来稍微对比一下这两种不同东西.
基础的概念我就不放了,大家可以先去了解一下,我这里只提一些重要的。

RXJAVA:链式编程,切换线程贼方便.实现异步操作,
存在的缺点:学习成本较高,操作符比较多,回调多,但比较灵活

协程:线程中的“线程”,实现异步操作,切换线程也方便,结构式并发.

LiveData:响应式编程,跟随生命周期。
存在的缺点:无法在io线程中setvalue,而postvalue则会存在丢数据的情景

Flow:冷流一对一,statteflow热流和liveData相似,但仍然可以在io线程中发送数据.有背压功能

3.分析

如果你仍然在用Java开发Android请尽情进行改变吧,kotlin可太香了!学到了kotlin,那么特有的协程和Flow你不用它,是不是有点浪费了.
我们可以看到,我们常用RXJAVA中的异步操作,链式编程,切换线程,在协程中也是可以完美实现的,在写代码的时候让人方便阅读(可以往下面看).
而LiveData中最大的坑postValue可以通过stateflow弥补,那么我们使用Flow可没有什么太大的问题.
别说那么多,上代码就更直观的看到问题出现在哪里了.
在这里插入图片描述

4.代码对比

我们来用RXJAVA写一段异步操作并且在Fragment中进行监听响应是什么样的一个效果.
0.Fragment

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    val retrofitViewModel = ViewModelProvider(requireActivity()).get(retrofitViewModel::class.java)
  retrofitViewModel.TextLiveData.observe(this,{
            Log.d(TAG, "onCreate: $it")
        })
 retrofitViewModel.viewModelScope.launch {
            retrofitViewModel.TextFlow.collect {
                Log.d(TAG, "onCreate:我们来看一下订阅后的情况: $it")
                //Add ViewMethod
            }
        }
}

1.RXJAVA+LiveData+viewModel

class retrofitViewModel : ViewModel() {
	val TextLiveData by lazy {
        MutableLiveData<Int>().also {
            Observable.create(ObservableOnSubscribe<Int?> { emitter ->
                emitter.onNext(1)
                emitter.onComplete()
            }).subscribeOn(Schedulers.io())
                    .subscribe(object : Observer<Int?> {
                        override fun onSubscribe(d: Disposable) {
                            println("onSubscribe=$d")
                        }


                        override fun onError(e: Throwable) {
                            println("onError=$e")
                        }

                        override fun onComplete() {
                            println("onComplete")
                        }

                        override fun onNext(value: Int?) {
                            //it.value = value 这样是不行的
                            it.postvalue(value)
                        }
                    })

        }
    }
}

2.协程+StateFlow
class retrofitViewModel : ViewModel() {

  val TextFlow by lazy {
        MutableStateFlow(0).also {
            viewModelScope.launch(Dispatchers.IO) {
                it.value = 1
            }
        }
    }

我们来看一下结果
在这里插入图片描述
可以明显的看到,两个东西实现了同一个功能,异步设置某值使得Fragment可以监听到值的改变并且进行响应.但是在代码量上的区可大了.而且StateFlow是肯定有初始值的

我们再来看一下在协程和Rxjava中并发中的不同

RXJAVA使用flapMap进行并发:

fun RxJavaParallel(){
        val list = Arrays.asList(1,2,3)
        Observable.fromIterable(list).flatMap{integer->
            Log.d(TAG, "RxJavaParallel: TASK_$integer Start:"+System.currentTimeMillis())

            getObservable(integer)
        }.subscribe(object : Observer<String?> {
            override fun onSubscribe(d: Disposable) {
                println("onSubscribafgsdfgre=$d")
            }


            override fun onError(e: Throwable) {
            }

            override fun onComplete() {

            }

            override fun onNext(value: String?) {
                //TODO("Not yet implemented")
                Log.d(TAG, "onNext: 接收发送的任务:$value")
            }
        })
    }

    fun getObservable(integer: Int): Observable<String?>? {
        return Observable.create(ObservableOnSubscribe<String?> { emitter ->
            emitter.onNext("第" + integer + "圆球的第1个棱形任务")
            Thread.sleep((1 * 1000).toLong())
            emitter.onComplete()
            Log.d(TAG, "RxJavaParallel: TASK_ finish:"+System.currentTimeMillis())

        }).subscribeOn(Schedulers.newThread())
    }

协程并发:
(结构化并发的话使用async),这里的并发只是不需要等待返回值所以直接使用launch
结构化并发是当其中任何一个失败后, 应该取消另一个协程的计算. 这就是所谓的


    fun CoroutineParallel(){
        viewModelScope.launch {
            launch {
                Log.d(TAG, "CoroutineParallel: TASK_1 Start:"+System.currentTimeMillis())
                delay(1000)
                Log.d(TAG, "CoroutineParallel: TASK_1 Finish:"+System.currentTimeMillis())
            }
            launch {
                Log.d(TAG, "CoroutineParallel: TASK_2 Start:"+System.currentTimeMillis())
                delay(1000)
                Log.d(TAG, "CoroutineParallel: TASK_2 Finish:"+System.currentTimeMillis())
            }

        }
    }

结果:
在这里插入图片描述
可以看到的是大家干的都是一件事,延时1秒(阻塞)然后输出,但是在概念理解和代码阅读上,协程确实有不少的优势.

5.增加Retrofit+Okhttp3(终极版)

Rxjava+Retrofit是我们常用的网络请求框架了…
当协程出来的时候,Retrofit也很快的支持了协程…
然后我们来看一下这两个不同之处…

构建okhttp客户端和retrofit.

 fun createGithubApi(): NormalInterface {
                val logger = HttpLoggingInterceptor()
                logger.level = HttpLoggingInterceptor.Level.BASIC

                val client = OkHttpClient.Builder()
                        .addInterceptor(logger)
                        .connectTimeout(30 * 1000, TimeUnit.MILLISECONDS)//连接超时
                        .readTimeout(20 * 1000, TimeUnit.MILLISECONDS)//读取超时,是否能读取到内容
                        .retryOnConnectionFailure(true)//重连
                        .build()
                return Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .client(client)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build()
                        .create(NormalInterface::class.java)
            }

定义API接口,注意的是retrofit返回的是Observable.而协程是RepoSearchResponse

interface NormalInterface :BaseApi{
   //这是RXJAVA
    @GET("search/repositories?sort=stars")
    fun searchRepos_X(
            @Query("q") query: String,
            @Query("page") page: Int,
            @Query("per_page") itemsPerPage: Int
    ): Observable<RepoSearchResponse>

    //这是协程
    @GET("search/repositories?sort=stars")
    suspend fun searchRepos(
            @Query("q") query: String,
            @Query("page") page: Int,
            @Query("per_page") itemsPerPage: Int
    ): RepoSearchResponse
data class RepoSearchResponse(
        @SerializedName("total_count") val total: Int = 0,
)
}

重点来了,我们在viewModel中启用协程加入到StateFlow中

  val TextFlow_Retrofit by lazy {
        MutableStateFlow(RepoSearchResponse()).also {
            viewModelScope.launch(Dispatchers.IO) {
                it.value = retrofitUse.createGithubApi().searchRepos("Android", 0, 20)

            }
        }
    }

另外一个重点,viewModel中的LiveData使用Rxjava+Retrofit发送网络请求

    //Rxjava+LiveData+retrofit+okhttp
    val TextLiveData_Retrofit by lazy {
        MutableLiveData<RepoSearchResponse>().also {

            retrofitUse.createGithubApi_X().searchRepos_X("Android", 0, 20).
            subscribeOn(Schedulers.io())
                    .subscribe(object:Observer<RepoSearchResponse>{
                        override fun onSubscribe(d: Disposable?) {
                           // TODO("Not yet implemented")
                        }
                        override fun onNext(value: RepoSearchResponse?) {
                            //TODO("Not yet implemented")
                            it.value = value
                        }
                        override fun onError(e: Throwable?) {
                           // TODO("Not yet implemented")
                        }
                        override fun onComplete() {
                           // TODO("Not yet implemented")
                        }
                    })
        }
    }

看代码大家应该也明白的差不多了…我发现网上还是感觉比较少这种比较出来的,虽然很基础,但是这样也让人更加的直观的发现这两种不同的情况.
总结一下:
RXJAVA+Retrofit 的网络请求确实也是好用的,RxJava中的操作符和学习难度是比较大的,而且封装起来也比较麻烦一些,但是代码层面上感觉阅读起来没有协程那么舒服.kotlin香也确实挺香的.
关于LiveData和Flow中的使用,学习之后是感觉在Kotlin中是比较适合Flow的.
好了,虽然官方是kotlin First,里面的高阶函数 ,协程,Flow都是比较基础也重要的特性,希望自己再接再厉,继续学习下去吧
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RetrofitRxJavaLiveData是Android开发中常用的三个库,用于提升网络请求和数据响应的效率和易用性。 首先来说说Retrofit,它是Square公司开发的一个网络请求库,可以简化HTTP请求的过程。具体来说,Retrofit通过注解方式定义API接口,支持多种数据格式的解析,如JSON、XML等,提供了丰富的请求方法和参数,可以使用线程池进行并发请求。Retrofit可以根据接口的定义,自动将HTTP请求转化为对应的Java方法调用,并将服务器返回的数据转化为Java对象。通过Retrofit,我们可以轻松地进行网络请求,提高了开发效率。 然后是RxJavaRxJava基于观察者模式和函数式编程思想,是一个强大的异步编程库。它提供了丰富的操作符和线程调度器,可以轻松地处理复杂的异步任务。通过RxJava,我们可以通过链式调用的方式组合多个异步操作,将它们串行或并行执行,还可以添加错误处理和重试机制。RxJava可以与Retrofit配合使用,通过它的观察者模式,可以实现将网络请求结果流式化,使得异步任务的处理更加简洁和灵活。 最后是LiveDataLiveData是Google在Android Architecture Components中引入的一个观察者模式类。LiveData具有生命周期感知能力,可以根据Activity或Fragment的生命周期自动管理数据的更新和释放,避免了内存泄漏和空指针异常。LiveData还支持后台线程发送数据,可以与RxJava搭配使用来实现异步数据更新。LiveData使得数据的处理更加安全可控,为开发者提供了一种便捷的方式来更新UI和响应数据变化。 综上所述,Retrofit提供了简洁的网络请求接口,RxJava提供了强大的异步编程能力,LiveData提供了响应式的数据更新机制。它们三者的结合使得网络请求和数据响应的处理更加简单高效,提高了开发效率和代码质量。 ### 回答2: RetrofitRxJavaLiveData是三种在Android开发中经常使用的库,用于进行网络请求和响应处理、异步操作和数据监听。 Retrofit是一种用于处理网络请求的库,它能够将网络请求与后台API进行连接,通过定义接口和请求方法,方便地进行网络请求和处理响应结果。Retrofit通过注解的方式定义网络请求方式、URL等信息,结合Gson等库进行数据解析,使得网络请求变得简单高效。 RxJava是一种响应式编程库,它能够方便地实现异步操作和事件流处理。通过使用Observables(被观察者)和Subscribers(观察者),我们可以将异步任务和数据流以扁平化的方式进行处理。RxJava提供了丰富的操作符,能够方便地实现异步请求、线程切换、数据过滤、转换等功能,使得代码逻辑更加简洁和可读。 LiveData是一种用于在Android应用中实现数据监听的库。LiveData可以感知生命周期并自动更新界面数据,能够保证数据的一致性和UI的正确性。LiveData可以与ViewModel结合使用,通过观察数据的变化来更新UI。与传统的观察者模式相比,LiveData具有更丰富的功能,例如避免内存泄漏、解决配置变化等问题。 综上所述,Retrofit是用于处理网络请求的库,通过简单高效的方式连接后台API;RxJava是用于实现异步操作和事件流处理的库,提供丰富的操作符;LiveData是用于在Android应用中实现数据监听的库,能够自动更新界面数据。这三个库的结合使用可以更加方便地进行网络请求、数据处理和UI更新。 ### 回答3: RetrofitRxJavaLiveData都是在Android开发中常用的工具或库。它们各自有着不同的功能和用途。 Retrofit是一个用于网络请求的库,它能够更方便地进行网络通信。通过Retrofit,我们可以定义网络请求的接口,定义请求的方法和参数,并且可以方便地处理返回的数据。Retrofit底层使用OkHttp库,可以实现网络请求的异步调用和线程切换,提高了网络请求的效率和稳定性。 RxJava是一个基于观察者模式的库,它提供了一套丰富的函数式编程接口,能够处理异步事件流。通过RxJava,我们可以轻松地创建、转换和操作Observable(被观察者),并且可以使用丰富的操作符来处理数据的过滤、变换和组合。RxJava还支持线程切换和错误处理,能够更好地处理异步任务。 LiveData是Android架构组件库中的一个组件,它用于在数据发生变化时通知观察者。LiveData可以感知Activity或Fragment的生命周期,并且会将数据更新通知给观察者。与传统的观察者模式相比,LiveData具有生命周期感知能力,可以避免内存泄漏和空指针异常。LiveData还支持数据的多个观察者,可以实现多个界面或组件之间的数据共享。 综上所述,Retrofit用于网络请求,RxJava用于处理异步事件流,LiveData用于在数据变化时通知观察者。它们在Android开发中各有不同的应用场景,能够提高开发效率和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值