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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM