更易于使用的Retrofit(不用写注解)
前言
聲明的時(shí)候比Retrofit更加簡(jiǎn)單,而且因?yàn)槭菑腞etrofit上改的,所以Retrofit能用的東西這個(gè)庫(kù)也能用
修改的地方
1.如果參數(shù)不加任何注解,則默認(rèn)是@Field,并且value為參數(shù)名(使用了kt反射,所以使用該特性必須用kt文件)
Retrofit原來(lái)的聲明和現(xiàn)在的聲明對(duì)比:
ps:發(fā)現(xiàn)目前kt反射還是效率很低,所以建議將獲取Call的方法放到子線程中,或者在初始化的時(shí)候預(yù)加載
比如:
//先創(chuàng)建出retrofit對(duì)象,然后create出動(dòng)態(tài)代理,create后再在子線程處理預(yù)加載val retrofit=xxxval post = retrofit.create(IPostRequest::class.java)submitToCacheThreadPool {//在子線程,可能需要幾秒,所以在啟動(dòng)十秒內(nèi)可能會(huì)用到的方法就手動(dòng)聲明@field吧!//預(yù)初始化所有的方法,使用時(shí)更快,注意需要在子線程調(diào)用,否則會(huì)造成anr,且由于將所有方法載入,所以會(huì)增加內(nèi)存消耗,屬于餓漢式(空間換時(shí)間)retrofit.preInit(IPostRequest::class.java)}2.POST注解自帶FormUrlEncoded注解,可以在第二個(gè)參數(shù)isUseFormUrlEncoded設(shè)置為false(且如果沒(méi)有參數(shù)就自動(dòng)變?yōu)閒alse),默認(rèn)為自動(dòng)判斷
ps:再也不用在寫的時(shí)候看有沒(méi)有參數(shù)加@FormUrlEncoded注解了,或者刪除參數(shù)的時(shí)候忘了刪該注解引起的崩潰!!!
Retrofit原來(lái)的聲明和現(xiàn)在的聲明對(duì)比:
3.如果方法沒(méi)有加注解,就默認(rèn)加上POST和FormUrlEncoded注解(參數(shù)為空不加此注解),并且method名字=url($代替/)(如果是kt就這樣寫: ?`user$login` ?)
Retrofit原來(lái)的聲明和現(xiàn)在的聲明對(duì)比:
ps:因?yàn)閗t的方法名不支持$符號(hào),所以需要兩邊需要加? `? ?,而java是支持的(但java無(wú)法享受kt反射的便捷)
pps:該方式是相當(dāng)于增加了一個(gè)可選項(xiàng),不是必選!!!(免杠聲明)
ppps:根據(jù)kt特性,可以使用下面的方式來(lái)在接口中聲明一個(gè)無(wú)參的get方法(不過(guò)可能有些雞肋)
val info: Call<String> //它的url就是getInfo val `test$123`: Call<String> //它的url就是getTest/123 方法名是getTest$123pppps:增加修改分隔符的功能,可以將$切換成任意字符串來(lái)代替/? 將$修改成_只需要這一行代碼即可: Retrofit.Builder().xxx.setMethodDelimiter("_")
4.程序運(yùn)行中途可以修改Retrofit的baseUrl
這個(gè)沒(méi)什么好說(shuō)的
5.可以修改沒(méi)有注解時(shí)的默認(rèn)注解
val retrofit: Retrofit = Retrofit.Builder().baseUrl(HttpConfig.ROOT_URL.toString()).defaultAnnotation(GET::class.java)//這一行?可以將默認(rèn)的POST注解切換為GET注解,參數(shù)的注解也從Field注解切換為Query注解
ps:該方法僅支持GET和POST
6.將方法內(nèi)所有參數(shù)合并為一個(gè)參數(shù)
比如:本來(lái)參數(shù)是{"a":1,"b":2},可以合并成{"str":"{"a":1,"b":2}"}? ? 因?yàn)橛械暮蠖藭?huì)將所有參數(shù)合并成一個(gè)并將其加密,所以考慮到有這個(gè)需求就增加了一個(gè)功能,開啟只需要在初始化Retrofit的時(shí)候加入以下一行
val retrofit: Retrofit = Retrofit.Builder().xxx.setSingleParameter("str")//這一行就開啟了合并參數(shù),傳null表示關(guān)閉(默認(rèn)).build()開啟后其他都不需要修改即可合并參數(shù)
如果想單獨(dú)開啟某個(gè)方法或關(guān)閉某個(gè)方法就可以使用方法注解:
@MergeParameter("str")//在沒(méi)有全局配置的情況下開啟,或在全局配置和該方法配置的key不相同時(shí)可以單獨(dú)修改
@NotMergeParameter?//如果開啟了全局配置,則關(guān)閉該方法的合并參數(shù)
ps:該方法僅支持GET的Query和POST的Field
7.支持自定義Retrofit.Call對(duì)象來(lái)攔截默認(rèn)的OkHttp的Call請(qǐng)求網(wǎng)絡(luò)或做其他事情
Retrofit.Builder().baseUrl(Urls.HTTP_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).callFactory(PostRequest.client)//下面這一行.setServiceMethodFactory(SocketServiceMethodFactory(SocketManage.manager, socketAdapter, false)).build().create(IPostRequest::class.java)ps:比如用于Socket請(qǐng)求,源碼可以參考:https://github.com/ltttttttttttt/Retrofit_SocketCallAdapter? ,使用可以參考:https://blog.csdn.net/qq_33505109/article/details/114189564
8.可以攔截短url并生成hook后的url(包括@POST之類和用@URL)
Retrofit.Builder().baseUrl("xxx")xxx.setHandlerUrlListener { oldUrl, method ->//這行//將原有的oldUrl(短url)轉(zhuǎn)換成你hook的url//比如將所有短url前面加上 version/ 可以這樣return@setHandlerUrlListener "version/" + oldUrl}9.更簡(jiǎn)單的聲明返回值?
一般我們?cè)诮涌诶锫暶鞣祷刂刀紩?huì)在原有基礎(chǔ)上包一層,比如Call<BaseBean<XXX>>,這樣寫起來(lái)比較麻煩,而且容易忘了寫封裝的那一層
而使用下面的方式可以簡(jiǎn)化書寫,其實(shí)用的是kt的特性,但估計(jì)有的同學(xué)不知道
首先在接口文件的最外層下上下面的type聲明(最外層表示跟這個(gè)接口同級(jí)別)
然后就可以在接口里直接簡(jiǎn)寫了,名字可以你自己起,可以看到打開這個(gè)方法的詳情,它會(huì)提示你他的返回類型和具體返回類型
10.可以使用默認(rèn)參數(shù),聲明的時(shí)候就可以將常量(或確認(rèn)的值)直接聲明好,調(diào)用的時(shí)候就不用傳了
這個(gè)其實(shí)也是kt的特性,沒(méi)什么好說(shuō)的
使用方式
在根項(xiàng)目的build.gradle文件中加入:
allprojects {repositories { ...maven { url 'https://jitpack.io' }} }app的build.gradle中加上
dependencies{...implementation 'com.github.ltttttttttttt:retrofit:1.3.5'implementation 'org.jetbrains.kotlin:kotlin-reflect:1.4.10'//todo 如果需要用到gson的攔截器之類的,但是其中包含的有原版的retrofit的引用,會(huì)導(dǎo)致沖突,所以可以使用下面的方法來(lái)去掉本引用的某個(gè)遠(yuǎn)程依賴implementation 'com.squareup.retrofit2:converter-gson:2.7.0' exclude module: 'retrofit' }需要開啟java8
android{...compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8} }然后按照Retrofit的正常方式使用就可以了
混淆代碼
#注:com.lt開頭的需要換成你自己的包名-keepclassmembers public interface com.lt.http.HttpFunctions {*;}#網(wǎng)絡(luò)請(qǐng)求封裝不能被混淆 -keep class kotlin.reflect.jvm.internal.impl.load.java.**{*; }#防止kt反射被混淆 -keep class kotlin.Metadata{*; }#防止kt元注解被混淆 -keep class com.lt.model.** { *;}#實(shí)體類不能被混淆,直接設(shè)置了一個(gè)文件夾# Retrofit-retrofit2 -dontnote retrofit2.Platform$IOS$MainThreadExecutor -dontwarn retrofit2.Platform$Java8 -keepattributes Signature -keepattributes Exceptions -keep class retrofit2.Default*{*; }#相應(yīng)序列化的,我用的kt序列化 -keepattributes *Annotation*, InnerClasses -dontnote kotlinx.serialization.SerializationKt -keep,includedescriptorclasses class com.lt.model.**$$serializer { *; } # <-- change package name to your app's -keepclassmembers class com.lt.model.** { # <-- change package name to your app's*** Companion; } -keepclasseswithmembers class com.lt.model.** { # <-- change package name to your app'skotlinx.serialization.KSerializer serializer(...); }#OkHttp -dontwarn okhttp3.** -keep class okhttp3.**{*;} -keep interface okhttp3.**{*;} -keepattributes Signature -keepattributes *Annotation* -dontwarn com.squareup.okhttp.** -keep class com.squareup.okhttp.**{*;} -keep interface com.squareup.okhttp.**{*;}#OkIo -dontwarn java.nio.file.* -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement -dontwarn okio.** -keep class okio.**{*;} -keep interface okio.**{*;}最后
如果想自定義封裝網(wǎng)絡(luò)請(qǐng)求,又想使用動(dòng)態(tài)代理方式,可以參考這一篇https://blog.csdn.net/qq_33505109/article/details/104920101
項(xiàng)目是fork的Retrofit,本項(xiàng)目是開源的,github地址:https://github.com/ltttttttttttt/retrofit
如果有問(wèn)題或者建議請(qǐng)?jiān)u論留言
(經(jīng)測(cè)試,300多個(gè)方法的接口(從線上項(xiàng)目copy出來(lái)測(cè)試的,三千多行),用這種方式,除了前兩次,后面獲取Call的性能竟然比原來(lái)的還快一點(diǎn),嘿嘿)
end
總結(jié)
以上是生活随笔為你收集整理的更易于使用的Retrofit(不用写注解)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 接入Tinker热修复和踩坑
- 下一篇: 更新至Android Studio4.1