前言
声明的时候比Retrofit更加简单,而且因为是从Retrofit上改的,所以Retrofit能用的东西这个库也能用
修改的地方
1.如果参数不加任何注解,则默认是@Field,并且value为参数名(使用了kt反射,所以使用该特性必须用kt文件)
Retrofit原来的声明和现在的声明对比:
ps:使用了kt反射,并且因为没有声明注解可能会对自定义Converter并检查注解时有影响,但是经测试和使用,并不会,如果出现问题请提出来
2.POST注解自带FormUrlEncoded注解,可以在第二个参数isUseFormUrlEncoded设置为false(且如果没有参数,默认为false)
Retrofit原来的声明和现在的声明对比:
3.如果方法没有加注解,就默认加上POST和FormUrlEncoded注解(参数为空不加此注解),并且method名字=url($代替/)(如果是kt就这样写: `user$login` )
Retrofit原来的声明和现在的声明对比:
ps:因为kt的方法名不支持$符号,所以需要两边需要加 ` ,而java是支持的(但java无法享受kt反射的便捷)
pps:该方式是相当于增加了一个可选项,不是必选!!!(免杠声明)
ppps:根据kt特性,可以使用下面的方式来在接口中声明一个无参的get方法(不过可能有些鸡肋)
val info: Call<String> //它的url就是getInfo
val `test$123`: Call<String> //它的url就是getTest/123 方法名是getTest$123
4.程序运行中途可以修改Retrofit的baseUrl
这个没什么好说的
使用方式
在根项目的build.gradle文件中加入:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
app的build.gradle中加上
dependencies{
...
implementation 'com.github.ltttttttttttt:retrofit:1.1.9'
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.4.10'
//todo 如果需要用到gson的拦截器之类的,但是其中包含的有原版的retrofit的引用,会导致冲突,所以可以使用下面的方法来去掉本引用的某个远程依赖
implementation 'com.squareup.retrofit2:converter-gson:2.7.0' exclude module: 'retrofit'
}
需要开启java8
android{
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
然后按照Retrofit的正常方式使用就可以了
混淆代码
#注:com.lt开头的需要换成你自己的包名
-keepclassmembers public interface com.lt.http.HttpFunctions {*;}#网络请求封装不能被混淆
-keep class kotlin.reflect.jvm.internal.impl.load.java.**{*; }#防止kt反射被混淆
-keep class kotlin.Metadata{*; }#防止kt元注解被混淆
-keep class com.lt.model.** { *;}#实体类不能被混淆,直接设置了一个文件夹
# Retrofit-retrofit2
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions
#相应序列化的,我用的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's
kotlinx.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.**{*;}
初始化优化
为了动态代理和kt反射KFunction不阻塞主线程,需要将其在初始化时放在子线程中,比如在init方法中,在子线程调用{Retrofit.Builder().xxx.login}//这样只拿到了一个Call(或者Observer),不会调用接口,却初始化了比较耗时的部分,而获取其他方法的时候由于动态代理已经实例化并且kt function反射已经初始化完成,会获取的很快(使用获取过的方法的Call对象一般不到1毫秒,使用新方法的Call对象3毫秒以下,其是正常Retrofit的获取时间)
最后
如果想自定义封装网络请求,又想使用动态代理方式,可以参考这一篇https://blog.csdn.net/qq_33505109/article/details/104920101
项目是fork的Retrofit,本项目是开源的,github地址:https://github.com/ltttttttttttt/retrofit
如果有问题或者建议请评论留言
(经测试,300多个方法的接口(从线上项目copy出来测试的,三千多行),用这种方式,除了前两次,后面获取Call的性能竟然比原来的还快一点,嘿嘿)
end