Retrofit2/Rxkotlin网络请求的封装

作者: 我要在河边钓一整天的鱼 | 来源:发表于2017-11-07 18:02 被阅读129次

    参考资料

    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的使用这里就不做叙述了。

    项目地址


    感谢观赏

    相关文章

      网友评论

        本文标题:Retrofit2/Rxkotlin网络请求的封装

        本文链接:https://www.haomeiwen.com/subject/bygjmxtx.html