參考資料
1、給初學者的RxJava2.0教程(總共有九篇)
2、Retrofit
目的
1、為了以後更改庫的方便網路請求庫不直接暴露介面;
2、對於網路的錯誤進行統一的處理;
3、View知道請求的結果,但是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>>>
}
複製程式碼
二、請求結構的統一處理
下面是我們公司萬年不變的請求結構:
{
code: Int,
data: [],
message: String
}
複製程式碼
其中只是根據data的不同型別進行更改就好了,今天使用的豆瓣的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?)
複製程式碼
三、請求後的返回格式
直接擼程式碼
data class Result(var status: ResultStauts, var errorMessage: String?)
enum class ResultStauts {
succeed, faild
}
複製程式碼
四、HttpClient實現
Retrofit的建立
retrofit = Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(ApiServers.BASE_URL)
.build()
複製程式碼
根據retrofit建立apiServers
apiServers = retrofit.create(ApiServers::class.java)
複製程式碼
請求對外暴露的介面,
這裡使用doOnEach這個操作符,他只是使用訊息中的資料但是對訊息沒有任何影響, 這裡和RxSwift的DoOn差不多(RxSwift中建立一個新的訊息但是對原來訊息沒有任何影響)
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("資料返回錯誤")
}
// 這裡要是有code相關錯誤的可以統一處理
return t.subjects!!
}
}).doOnEach(object : Observer<T>{
override fun onNext(t: T) {
}
override fun onError(e: Throwable) {
// 處理請求過程中錯誤
}
override fun onSubscribe(d: Disposable) {
}
override fun onComplete() {
}
})
}
複製程式碼
Model中的使用
在請求中我們對請求中的錯誤已經做過處理,這裡只是將請求的結果、錯誤資訊回撥給ViewModel, 資料直接儲存在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的使用這裡就不做敘述了。
感謝觀賞