Android 网络框架:Retrofit2一篇就够了(2020-4-23)

前言

 目前Retrofit2、RxJava2、OkHttp3可以说非常火,经常被一并提及,因此学习它们是非常有必要的。
 本系列主要写Retrofit2的使用,Retrofit2其实并不复杂,使用它只是为了规范我们网络请求的代码,深入学习之后会发现Retrofit2可以让代码可读性更好。
 Retrofit的特点就是使用注解来描述一个http请求,本系列会在下一章具体讲解每一个注解的使用。
 retrofit官网地址:https://square.github.io/retrofit/


1 入门

 GRADLE

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

 也可以在官网下载JAR包,GitHub上可以查看源代码和示例

 ①创建实体类接收Json。

data class WordData constructor(var reason:String,var result:Any,var error_code:String)

 ②将HTTP API转换成接口,如下所示:

interface WordService{
    @GET("query")
    fun getWord(@Query("word") word: String, @Query("dtype") dtype: String,@Query("key") key: String): Call<WordData>    
}

 ③生成Retrofit实现接口实例。

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

 var wordService = retrofit.create(WordService::class.java)

 ④调用接口的方法去异步请求网络,并通过callback回调请求结果。
  (示例使用的是聚合数据的免费接口,key是错误的,正确key的Json太长....)

 wordService.getWord("你","json","c5c6a09be5cdb2047")
    .enqueue(object : Callback<WordData> {
    override fun onFailure(call: Call<WordData>, t: Throwable) {
        Log.d(tag,"onFailure")
    }
    override fun onResponse(call: Call<WordData>, response: Response<WordData>) {
        Log.d(tag,response.body().toString())
    }
 })

 请求回来的数据如下所示:

 WordData(reason=错误的请求KEY, result=null, error_code=10001)

 至此,已经使用Retrofit完成一个网络请求。
 你也可以通过call调用同步网络请求代码如下所示:

 var wordService = wordService.getWord("你","json","c5c6a09be5cdb2047")
 var wordData = wordService.execute().body() as WordData

2 Converters

 retrofit可以配置不同的工具来解析数据,例如gson、xml等等。

  • Gson: com.squareup.retrofit2:converter-gson
  • Simple XML: com.squareup.retrofit2:converter-simplexml

 示例代码如下所示:

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

 通过调用addConverterFactory()方法,添加GsonConverterFactory。


3 OkHttpClient

 Retrofit也可以自定义OkHttpClient,代码如下所示:

 val dispatcher = Dispatcher(Executors.newFixedThreadPool(20))
        dispatcher.setMaxRequests(20)
        dispatcher.setMaxRequestsPerHost(1)

 val okHttpClient = OkHttpClient.Builder()
            .dispatcher(dispatcher)
            .connectionPool(ConnectionPool(100, 30, TimeUnit.SECONDS))
            .build()

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()

4 Retrofit2 + RxJava2

 在Retrofit中使用RxJava2,接口的定义和网络请求和上面略有不同,而且需要调用addCallAdapterFactory添加对RxJava2的支持。

Retrofit2

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'

Rxjava2

implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

①将HTTP API转换成接口,但是返回参数需要改变成Observable<WordData>,如下所示:

interface WordService {
    @GET("/xhzd/query")
    fun getWord(@Query("word") word: String, @Query("dtype") dtype: String,@Query("key") key: String): Observable<WordData>
}

②调用addCallAdapterFactory方法传入RxJava2CallAdapterFactory.create()生成Retrofit,然后实现接口实例。

var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpClient)
            .build()
var wordService = retrofit.create(WordService::class.java)

③使用RxJava2对数据进行处理,代码如下所示:

wordService.getWord("你", "json", "c5c6a09be5cdb2047")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d(tag, it.toString())
                }, {
                    Log.d(tag, "onFailure")
                })

可以看见日志输入如下所示:

WordData(reason=错误的请求KEY, result=null, error_code=10001)

5 高级写法

①首先使用Body定义Api

interface IApi {
        @POST("/xhzd/getUnreadRemind")
        fun getMessageRemind(@Body params: JsonObject?): Observable<BaseBean<RedPointBean>>
}

②然后可以使用JsonObject定义一个基础请求体,封装一些我们每次请求都会带的参数。

object BaseRequestParams {
    fun basePostParams(): JsonObject {
        val baseParams = JsonObject()
        baseParams.addProperty("device_id", DeviceUtil.getDeviceIMEI(getApplication()))
        baseParams.addProperty("platform", "android")
        return baseParams
    }
}

③最后进行请求

var mService = retrofit.create(IApi::class.java)
override fun getSearchRecommendWord(keyword: String): Observable<BaseBean<RecommendWordBean>> {
        val params = BaseRequestParams.basePostParams()
        params.addProperty("keyword", keyword)
        return mService.getMessageRemind(params)
}

总结

 Retrofit使用非常简单,首先转换接口,然后创建Retrofit实例,再实现接口,最后进行网络请求,回调处理数据。

转载自:https://www.jianshu.com/p/9eeae877ddb0?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

原文地址:https://www.cnblogs.com/Im-Victor/p/14103585.html