Retrofit的基本使用之后,可以搭配RxJava來進(jìn)行網(wǎng)絡(luò)申請,使得復(fù)雜的異步回調(diào)代碼變得比較簡單,比較容易讓人看懂
在retrofit的基礎(chǔ)上使用rxjava
接口方面要把call改成Observable,因?yàn)镽xJava是用的觀察者模式,代碼如下
@GET("news")
Observable<NewsList> getNews();
在retrofit創(chuàng)造的時(shí)候加上addCallAdapterFactory(RxJavaCallAdapterFactory.create()),因?yàn)閞etrofit支持Call類型的數(shù)據(jù),如果要支持Observable的話就要添加這句話。那么retrofit的創(chuàng)建就是
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.readhub.cn/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
Service service = retrofit.create(Service.class);
因?yàn)橛玫氖莚xjava,那么就是用觀察者模式,把網(wǎng)絡(luò)請求放到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");
}
}
});
這里成功了就會(huì)通知主線程去更改textview,可以說非常簡單就實(shí)現(xiàn)了異步的過程
在retrofit的基礎(chǔ)上使用kotlin協(xié)程
kotlin的協(xié)程也可以代替RxJava,用同步的方式寫出異步代碼,非常的簡潔。
接口部分代碼更改為
@GET("news")
suspend fun getNews():NewsList
這里就有個(gè)不同于以前的關(guān)鍵字suspend,這個(gè)是kotlin提供給我們的,他的作用就是當(dāng)執(zhí)行到這個(gè)函數(shù)時(shí),就會(huì)被掛起,線程可以繼續(xù)執(zhí)行接下來的方法。
這里我創(chuàng)建了一個(gè)viewmodel,在viewmodel提供的viewModelScope中對數(shù)據(jù)進(jìn)行處理
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" )
}
}
}
也是打印了每個(gè)新聞的的標(biāo)題,數(shù)據(jù)都在result中,可以拿個(gè)新數(shù)組存取起來,在ui中處理。
MainActivity則是應(yīng)該獲取到viewmodel,然后直接使用viewmodel中的getNews方法就好了
總結(jié)
協(xié)程的代碼沒有那么復(fù)雜,可以避免有時(shí)候人被繞進(jìn)去,只需按照正常的閱讀順序就可以了。也可以跟databinding一起使用,在viewmodel中把數(shù)據(jù)綁定到ui上面