更易于使用的Retrofit(不用写注解)

前言

声明的时候比Retrofit更加简单,而且因为是从Retrofit上改的,所以Retrofit能用的东西这个库也能用

远程依赖接入方式在最下面

ps:目前更推荐使用性能更好且跨平台的: ltttttttttttt/LazyPeopleHttp

修改的地方

1.如果参数不加任何注解,则默认是@Field,并且value为参数名(使用了kt反射,所以使用该特性必须用kt文件)

Retrofit原来的声明和现在的声明对比:

更易于使用的Retrofit(不用写注解)_第1张图片

ps:发现目前kt反射还是效率很低,所以建议将获取Call的方法放到子线程中,或者在初始化的时候预加载

比如:

        //先创建出retrofit对象,然后create出动态代理,create后再在子线程处理预加载
        val retrofit=xxx
        
        val post = retrofit.create(IPostRequest::class.java)
        submitToCacheThreadPool {
            //在子线程,可能需要几秒,所以在启动十秒内可能会用到的方法就手动声明@field吧!
            //预初始化所有的方法,使用时更快,注意需要在子线程调用,否则会造成anr,且由于将所有方法载入,所以会增加内存消耗,属于饿汉式(空间换时间)
            retrofit.preInit(IPostRequest::class.java)
        }

2.POST注解自带FormUrlEncoded注解,可以在第二个参数isUseFormUrlEncoded设置为false(且如果没有参数就自动变为false),默认为自动判断

ps:再也不用在写的时候看有没有参数加@FormUrlEncoded注解了,或者删除参数的时候忘了删该注解引起的崩溃!!!

Retrofit原来的声明和现在的声明对比:

更易于使用的Retrofit(不用写注解)_第2张图片

3.如果方法没有加注解,就默认加上POST和FormUrlEncoded注解(参数为空不加此注解),并且method名字=url($代替/)(如果是kt就这样写:  `user$login`  )

Retrofit原来的声明和现在的声明对比:

更易于使用的Retrofit(不用写注解)_第3张图片

ps:因为kt的方法名不支持$符号,所以需要两边需要加  `   ,而java是支持的(但java无法享受kt反射的便捷)

pps:该方式是相当于增加了一个可选项,不是必选!!!(免杠声明)

ppps:根据kt特性,可以使用下面的方式来在接口中声明一个无参的get方法(不过可能有些鸡肋)

val info: Call   //它的url就是getInfo
val `test$123`: Call    //它的url就是getTest/123    方法名是getTest$123

pppps:增加修改分隔符的功能,可以将$切换成任意字符串来代替/  将$修改成_只需要这一行代码即可: Retrofit.Builder().xxx.setMethodDelimiter("_")

4.程序运行中途可以修改Retrofit的baseUrl

这个没什么好说的

5.可以修改没有注解时的默认注解

val retrofit: Retrofit = Retrofit.Builder()
                .baseUrl(HttpConfig.ROOT_URL.toString())
                .defaultAnnotation(GET::class.java)//这一行

 可以将默认的POST注解切换为GET注解,参数的注解也从Field注解切换为Query注解

ps:该方法仅支持GET和POST

6.将方法内所有参数合并为一个参数

比如:本来参数是{"a":1,"b":2},可以合并成{"str":"{"a":1,"b":2}"}    因为有的后端会将所有参数合并成一个并将其加密,所以考虑到有这个需求就增加了一个功能,开启只需要在初始化Retrofit的时候加入以下一行

        val retrofit: Retrofit = Retrofit.Builder()
                .xxx
                .setSingleParameter("str")//这一行就开启了合并参数,传null表示关闭(默认)
                .build()

开启后其他都不需要修改即可合并参数

如果想单独开启某个方法或关闭某个方法就可以使用方法注解:

@MergeParameter("str")//在没有全局配置的情况下开启,或在全局配置和该方法配置的key不相同时可以单独修改

@NotMergeParameter //如果开启了全局配置,则关闭该方法的合并参数

ps:该方法仅支持GET的Query和POST的Field

7.支持自定义Retrofit.Call对象来拦截默认的OkHttp的Call请求网络或做其他事情

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请求,源码可以参考:GitHub - ltttttttttttt/Retrofit_SocketCallAdapter: Retrofit可以直接使用OkSocket来进行网络请求,Retrofit内的东西都不需要修改,只需要将OkHttpClient换成此即可  ,使用可以参考:使用Retrofit的方式请求Socket,且Socket可以和Http无缝切换_滔lt的博客-CSDN博客_retrofit websocket

8.可以拦截短url并生成hook后的url(包括@POST之类和用@URL)

            Retrofit.Builder()
                .baseUrl("xxx")
                xxx
                .setHandlerUrlListener { oldUrl, method ->//这行
                    //将原有的oldUrl(短url)转换成你hook的url
                    //比如将所有短url前面加上 version/  可以这样
                    return@setHandlerUrlListener "version/" + oldUrl
                }

9.更简单的声明返回值 

一般我们在接口里声明返回值都会在原有基础上包一层,比如Call>,这样写起来比较麻烦,而且容易忘了写封装的那一层

而使用下面的方式可以简化书写,其实用的是kt的特性,但估计有的同学不知道

首先在接口文件的最外层下上下面的type声明(最外层表示跟这个接口同级别)

然后就可以在接口里直接简写了,名字可以你自己起,可以看到打开这个方法的详情,它会提示你他的返回类型和具体返回类型

更易于使用的Retrofit(不用写注解)_第4张图片

10.可以使用默认参数,声明的时候就可以将常量(或确认的值)直接声明好,调用的时候就不用传了

这个其实也是kt的特性,没什么好说的

更易于使用的Retrofit(不用写注解)_第5张图片

11.可以直接传递list的json

 使用过retrofit,然后把list当参数传递给后台的都知道,默认retrofit是不支持此功能的(或者说实现的比较怪异),一般可以通过将list转为json字符串来发送(虽然其type变成了String)

使用此框架可以简单的传递list json,只需要给list参数加上一个@ParameterIsList注解即可:

ps:如果要自定义解析参数的话可以参考这篇: 使用Retrofit时,对参数进行加密_李小白lt的博客-CSDN博客_retrofit 加密 

使用方式

在根项目的build.gradle文件中加入:


allprojects {
    repositories {
...
        maven { url 'https://jitpack.io' }
    }
}

app的build.gradle中加上

dependencies{
    ...
    implementation 'com.github.ltttttttttttt:retrofit:1.3.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
-keep class retrofit2.Default*{*; }

#相应序列化的,我用的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.**{*;}

最后

如果想自定义封装网络请求,又想使用动态代理方式,可以参考这一篇模仿Retrofit封装一个使用更简单的网络请求框架_滔lt的博客-CSDN博客

项目是fork的Retrofit,本项目是开源的,github地址:GitHub - ltttttttttttt/retrofit: A type-safe HTTP client for Android and the JVM

如果有问题或者建议请评论留言

(经测试,300多个方法的接口(从线上项目copy出来测试的,三千多行),用这种方式,除了前两次,后面获取Call的性能竟然比原来的还快一点,嘿嘿)

end

你可能感兴趣的:(java,提升效率,Kotlin,java,Android,提升效率,Retrofit,网络请求框架)