Retrofit搭配RxJava或者kotlin协程的基本网络请求

Retrofit的基本使用之后,可以搭配RxJava来进行网络申请,使得复杂的异步回调代码变得比较简单,比较容易让人看懂

在retrofit的基础上使用rxjava

接口方面要把call改成Observable,因为RxJava是用的观察者模式,代码如下

@GET("news")
    Observable<NewsList> getNews();

在retrofit创造的时候加上addCallAdapterFactory(RxJavaCallAdapterFactory.create()),因为retrofit支持Call类型的数据,如果要支持Observable的话就要添加这句话。那么retrofit的创建就是

Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl("https://api.readhub.cn/")
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                        .build();
Service service = retrofit.create(Service.class);

因为用的是rxjava,那么就是用观察者模式,把网络请求放到io线程,然后再去通知主线程去更改ui。

                  service.getNews()
                        .subscribeOn(Schedulers.io())//请求在IO线程中完成
                        .observeOn(AndroidSchedulers.mainThread())//通知主线程更改ui
                        .subscribe(new Subscriber<NewsList>() {
                            @Override
                            public void onCompleted() {

                            }
                            @Override
                            public void onError(Throwable e) {
                                Log.e(TAG, "onError: "+e );
                            }
                            @Override
                            public void onNext(NewsList newsList) {
                                //请求成功要做的事
                                for (News news : newsList.getNews()){
                                    Log.e(TAG, news.getTitle());
                                    textView.append(news.getTitle()+"\n");
                                }
                            }
                        });

这里成功了就会通知主线程去更改textview,可以说非常简单就实现了异步的过程

在retrofit的基础上使用kotlin协程

kotlin的协程也可以代替RxJava,用同步的方式写出异步代码,非常的简洁。
接口部分代码更改为

@GET("news")
suspend fun getNews():NewsList

这里就有个不同于以前的关键字suspend,这个是kotlin提供给我们的,他的作用就是当执行到这个函数时,就会被挂起,线程可以继续执行接下来的方法。
这里我创建了一个viewmodel,在viewmodel提供的viewModelScope中对数据进行处理

fun getNews(){
       viewModelScope.launch {
           try{
               val result = service.getNews()
               for (new:News in result.news!!){
                   Log.e(TAG, "OnSuccess${new.title}" )
               }
           }catch (e:Exception){
               e.printStackTrace()
               Log.e(TAG, "onError$e" )
           }
       }
   }

也是打印了每个新闻的的标题,数据都在result中,可以拿个新数组存取起来,在ui中处理。
MainActivity则是应该获取到viewmodel,然后直接使用viewmodel中的getNews方法就好了

总结

协程的代码没有那么复杂,可以避免有时候人被绕进去,只需按照正常的阅读顺序就可以了。也可以跟databinding一起使用,在viewmodel中把数据绑定到ui上面

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容