Android 網(wǎng)絡(luò)框架:Retrofit2一篇就夠了(2020-4-23)

前言

?目前Retrofit2值戳、RxJava2西篓、OkHttp3可以說(shuō)非秤冢火,經(jīng)常被一并提及岂津,因此學(xué)習(xí)它們是非常有必要的虱黄。
?本系列主要寫Retrofit2的使用,Retrofit2其實(shí)并不復(fù)雜寸爆,使用它只是為了規(guī)范我們網(wǎng)絡(luò)請(qǐng)求的代碼礁鲁,深入學(xué)習(xí)之后會(huì)發(fā)現(xiàn)Retrofit2可以讓代碼可讀性更好盐欺。
?Retrofit的特點(diǎn)就是使用注解來(lái)描述一個(gè)http請(qǐng)求,本系列會(huì)在下一章具體講解每一個(gè)注解的使用仅醇。
?retrofit官網(wǎng)地址:https://square.github.io/retrofit/


1 入門

?GRADLE

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

?也可以在官網(wǎng)下載JAR包冗美,GitHub上可以查看源代碼和示例

?①創(chuàng)建實(shí)體類接收J(rèn)son析二。

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

?②將HTTP API轉(zhuǎn)換成接口粉洼,如下所示:

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

?③生成Retrofit實(shí)現(xiàn)接口實(shí)例。

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

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

?④調(diào)用接口的方法去異步請(qǐng)求網(wǎng)絡(luò)叶摄,并通過(guò)callback回調(diào)請(qǐng)求結(jié)果属韧。
? (示例使用的是聚合數(shù)據(jù)的免費(fèi)接口,key是錯(cuò)誤的蛤吓,正確key的Json太長(zhǎng)....)

 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())
    }
 })

?請(qǐng)求回來(lái)的數(shù)據(jù)如下所示:

 WordData(reason=錯(cuò)誤的請(qǐng)求KEY, result=null, error_code=10001)

?至此宵喂,已經(jīng)使用Retrofit完成一個(gè)網(wǎng)絡(luò)請(qǐng)求。
?你也可以通過(guò)call調(diào)用同步網(wǎng)絡(luò)請(qǐng)求代碼如下所示:

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

2 Converters

?retrofit可以配置不同的工具來(lái)解析數(shù)據(jù)会傲,例如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()

?通過(guò)調(diào)用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泼疑,接口的定義和網(wǎng)絡(luò)請(qǐng)求和上面略有不同德绿,而且需要調(diào)用addCallAdapterFactory添加對(duì)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轉(zhuǎn)換成接口退渗,但是返回參數(shù)需要改變成Observable<WordData>移稳,如下所示:

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

②調(diào)用addCallAdapterFactory方法傳入RxJava2CallAdapterFactory.create()生成Retrofit,然后實(shí)現(xiàn)接口實(shí)例氓辣。

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對(duì)數(shù)據(jù)進(jìn)行處理秒裕,代碼如下所示:

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

可以看見(jiàn)日志輸入如下所示:

WordData(reason=錯(cuò)誤的請(qǐng)求KEY, result=null, error_code=10001)

5 高級(jí)寫法

①首先使用Body定義Api

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

②然后可以使用JsonObject定義一個(gè)基礎(chǔ)請(qǐng)求體袱蚓,封裝一些我們每次請(qǐng)求都會(huì)帶的參數(shù)钞啸。

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

③最后進(jìn)行請(qǐng)求

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)
}

總結(jié)

?Retrofit使用非常簡(jiǎn)單,首先轉(zhuǎn)換接口喇潘,然后創(chuàng)建Retrofit實(shí)例体斩,再實(shí)現(xiàn)接口,最后進(jìn)行網(wǎng)絡(luò)請(qǐng)求颖低,回調(diào)處理數(shù)據(jù)絮吵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忱屑,隨后出現(xiàn)的幾起案子蹬敲,更是在濱河造成了極大的恐慌暇昂,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴嗡,死亡現(xiàn)場(chǎng)離奇詭異急波,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瘪校,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門澄暮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人阱扬,你說(shuō)我怎么就攤上這事泣懊。” “怎么了麻惶?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵馍刮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我窃蹋,道長(zhǎng)渠退,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任脐彩,我火速辦了婚禮碎乃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惠奸。我一直安慰自己梅誓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布佛南。 她就那樣靜靜地躺著梗掰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嗅回。 梳的紋絲不亂的頭發(fā)上及穗,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音绵载,去河邊找鬼埂陆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛娃豹,可吹牛的內(nèi)容都是我干的焚虱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼懂版,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鹃栽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起躯畴,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤民鼓,失蹤者是張志新(化名)和其女友劉穎薇芝,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丰嘉,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恩掷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了供嚎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黄娘。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖克滴,靈堂內(nèi)的尸體忽然破棺而出逼争,到底是詐尸還是另有隱情,我是刑警寧澤劝赔,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布誓焦,位于F島的核電站,受9級(jí)特大地震影響着帽,放射性物質(zhì)發(fā)生泄漏杂伟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一仍翰、第九天 我趴在偏房一處隱蔽的房頂上張望赫粥。 院中可真熱鬧,春花似錦予借、人聲如沸越平。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)秦叛。三九已至,卻和暖如春瀑粥,著一層夾襖步出監(jiān)牢的瞬間挣跋,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工狞换, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留避咆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓哀澈,卻偏偏與公主長(zhǎng)得像牌借,于是被迫代替她去往敵國(guó)和親度气。 傳聞我的和親對(duì)象是個(gè)殘疾皇子割按,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容