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上面