參考資料
1、給初學(xué)者的RxJava2.0教程(總共有九篇)
2、Retrofit
目的
1、為了以后更改庫(kù)的方便網(wǎng)絡(luò)請(qǐng)求庫(kù)不直接暴露接口;
2、對(duì)于網(wǎng)絡(luò)的錯(cuò)誤進(jìn)行統(tǒng)一的處理;
3、View知道請(qǐng)求的結(jié)果,但是View不持有Modol。
Retrofit2封裝
一、ApiServers
直接上代碼
interface ApiServers {
companion object {
val BASE_URL: String = "https://api.douban.com/v2/movie/"
}
@GET("top250")
fun getMovies(@Query("page") page: Int, @Query("size") size: Int): Observable<Response<List<Subject>>>
}
二、請(qǐng)求結(jié)構(gòu)的統(tǒng)一處理
下面是我們公司萬(wàn)年不變的請(qǐng)求結(jié)構(gòu):
{
code: Int,
data: [],
message: String
}
其中只是根據(jù)data的不同類(lèi)型進(jìn)行更改就好了,今天使用的豆瓣的top250接口(“https://api.douban.com/v2/movie/top250”),所以Response如下:
data class Response<T>(var count: Int?,
var start: Int?,
var total: Int?,
var subjects: T?,
var title: String?)
三、請(qǐng)求后的返回格式
直接擼代碼
data class Result(var status: ResultStauts, var errorMessage: String?)
enum class ResultStauts {
succeed, faild
}
四、HttpClient實(shí)現(xiàn)
Retrofit的創(chuàng)建
retrofit = Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(ApiServers.BASE_URL)
.build()
根據(jù)retrofit創(chuàng)建apiServers
apiServers = retrofit.create(ApiServers::class.java)
請(qǐng)求對(duì)外暴露的接口,
這里使用doOnEach這個(gè)操作符,他只是使用消息中的數(shù)據(jù)但是對(duì)消息沒(méi)有任何影響, 這里和RxSwift的DoOn差不多(RxSwift中創(chuàng)建一個(gè)新的消息但是對(duì)原來(lái)消息沒(méi)有任何影響)
fun <T>request(observable: Observable<Response<T>>): Observable<T>{
return observable.toSchedulers().map(object : Function<Response<T>, T> {
override fun apply(t: Response<T>): T {
if (t.subjects == null) {
throw Exception("數(shù)據(jù)返回錯(cuò)誤")
}
// 這里要是有code相關(guān)錯(cuò)誤的可以統(tǒng)一處理
return t.subjects!!
}
}).doOnEach(object : Observer<T>{
override fun onNext(t: T) {
}
override fun onError(e: Throwable) {
// 處理請(qǐng)求過(guò)程中錯(cuò)誤
}
override fun onSubscribe(d: Disposable) {
}
override fun onComplete() {
}
})
}
Model中的使用
在請(qǐng)求中我們對(duì)請(qǐng)求中的錯(cuò)誤已經(jīng)做過(guò)處理,這里只是將請(qǐng)求的結(jié)果、錯(cuò)誤信息回調(diào)給ViewModel, 數(shù)據(jù)直接保存在Model中。
private fun getMovie(): Observable<Result> {
return Observable.create(object : ObservableOnSubscribe<Result> {
override fun subscribe(e: ObservableEmitter<Result>) {
httpClient.request(httpClient.getAPIServers().getMovies(mPage, mPageSize)).subscribe({t: List<Subject> ->
data.addAll(t)
e.onNext(Result(ResultStauts.succeed, null))
},{t: Throwable ->
e.onNext(Result(ResultStauts.faild, t.localizedMessage))
})
}
})
}
下面是ViewModel和View的使用這里就不做敘述了。
感謝觀(guān)賞