参考资料
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的使用这里就不做叙述了。
感谢观赏