├── README.md └── XRetrofit ├── .gitignore ├── Could ├── annotations ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── yanxuwen │ └── xretrofit_annotations │ └── annotation │ ├── method │ ├── DELETE.java │ ├── DOWNLOAD.java │ ├── FORM.java │ ├── GET.java │ ├── Headers.java │ ├── POST.java │ ├── PUT.java │ └── UPLOAD.java │ ├── param │ ├── Body.java │ ├── FilePath.java │ ├── Header.java │ ├── Param.java │ ├── Path.java │ └── Query.java │ └── service │ └── NetServiceClass.java ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yanxuwen │ │ └── xretrofit │ │ ├── MainActivity.java │ │ ├── MyApplication.java │ │ ├── RxSchedulers.java │ │ ├── bean │ │ ├── HomeInfoV5.java │ │ └── LoginBuild.java │ │ ├── callback │ │ ├── MyCallBack.java │ │ ├── MyProgressCallBack.java │ │ └── ServerException.java │ │ ├── converter │ │ ├── GsonConverterFactories.java │ │ ├── GsonRequestConverter.java │ │ ├── GsonResponseConverter.java │ │ ├── Rxjava2CallAdapter.java │ │ └── Rxjava2CallAdapterFactories.java │ │ └── http │ │ ├── HttpRequest.java │ │ └── NetService.java │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml ├── bintray.gradle ├── build.gradle ├── compiler ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── xretrofit │ └── compiler │ ├── ElementUtils.java │ ├── HttpServiceProcessor2.java │ └── create │ └── CreateClassUtils.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── install.gradle ├── jitpack.gradle ├── settings.gradle ├── versions.gradle └── xretrofit ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml └── java └── com └── xretrofit ├── CallAdapter ├── CallAdapter.java ├── MCallAdapter.java ├── ObjectCallAdapter.java ├── ObjectCallAdapterFactory.java └── ProgressCallAdapter.java ├── HttpException.java ├── HttpManager.java ├── Interceptor ├── DownloadResponseBody.java ├── ProgressListener.java └── UploadRequestBodyBody.java ├── Response.java ├── bean └── RequestParams.java ├── call ├── Call.java ├── OkHttpCall.java └── ProgressCall.java ├── callback ├── CallBack.java └── ProgressCallBack.java ├── converter ├── Converter.java ├── DownloadConverterFactories.java ├── DownloadResponseConverter.java ├── StringConverterFactories.java ├── StringResponseConverter.java ├── UploadConverterFactories.java └── UploadRequestConverter.java ├── method ├── MethodAnnotation.java ├── ParamAnnotation.java └── ServiceMethod.java ├── okhttp └── SslUtils.java └── utils ├── UrlUtils.java └── Utils.java /README.md: -------------------------------------------------------------------------------- 1 | #### 介绍 2 | XRetrofit 是一个极致模仿Retrofit 的风格代码,代码没有Retrofit 复杂,简单易懂。 3 | #### 4 | 支持`get`、`post`、`put`、`delete` 请求,这些使用都一样。 5 | 简化文件上传,跟下载 使用`@DOWNLOAD` 跟`@UPLOAD` 6 | 简化` post` 表单请求跟JOSN请求。 7 | 支持转换器,如果需要Gson的转换器,可以去demo那边去复制 8 | 支持适配器,内置跟Retrofit的`Call`,当然了String可以替换任意的类型,跟Retrofit一样 9 | 没有内置`Rxjava的适配器`,如果需要,自己去demo那边复制。 10 | ##### 区别 11 | `Retrofit` 属于运行时注解,通过动态代理生成一个代码 12 | `XRetrofit` 属于编译时注解,通过APT生成代码,如果要学习APT,可以操作这篇文章[《带你了解APT》点击传送门](https://www.jianshu.com/p/00dce41e5d00) 13 | 14 | ##### 依赖, 只支持androidX,没有supper版本 15 | ~~~ 16 | implementation 'com.yanxuwen.xretrofit:xretrofit:2.0.0' 17 | annotationProcessor 'com.yanxuwen.xretrofit:xretrofit-compiler:2.0.0' 18 | ~~~ 19 | ##### 依赖, 由于jcenter要跑路了,所以已迁移到jitpack 20 | ~~~ 21 | implementation 'com.github.yanxuwen:xretrofit:0.0.8' 22 | annotationProcessor 'com.github.yanxuwen.xretrofit:compiler:0.0.8' 23 | ~~~ 24 | #### 使用方法,跟Retrofit一样,要定义接口,唯一区别在于在类上面要添加注解`@NetServiceClass` 25 | #### 定义接口,该例子分别写了`Rxjava` 、`Call` 、`同步请求`的使用 26 | ~~~ 27 | @NetServiceClass 28 | public interface NetService { 29 | /** 30 | * Rxjava 适配器 31 | */ 32 | @GET("api/manage-home/v5/home/detail-v2") 33 | Observable get(@Query("page") int page, @Query("limit") int limit); 34 | 35 | /** 36 | * 自带Call 适配器 37 | */ 38 | @GET("api/manage-home/v5/home/{version}") 39 | Call get(@Path("version") String version, @Query("page") int page, @Query("limit") int limit); 40 | 41 | /** 42 | * 同步请求 43 | */ 44 | @GET("api/manage-home/v5/home/detail-v2") 45 | String get3(@Query("page") int page, @Query("limit") int limit); 46 | 47 | } 48 | ~~~ 49 | #### 执行请求,以Call 适配器为例子 50 | ~~~ 51 | public void onGet2(View view) { 52 | Call call = HttpRequest.getNetService().get("detail-v2", 0, 10); 53 | call.enqueue(new MyCallBack(this) { 54 | 55 | @Override 56 | public void success(HomeInfoV5 s) { 57 | Log.e("yxw", "onGet:" + s.getMsg()); 58 | } 59 | 60 | @Override 61 | public void fail(String msg) { 62 | Log.e("yxw", "onGet:" + msg); 63 | } 64 | 65 | @Override 66 | public void cancel() { 67 | Log.e("yxw", "cancel"); 68 | } 69 | }); 70 | 71 | } 72 | ~~~ 73 | #### 执行请求,以Rxjava 适配器为例子 74 | ~~~ 75 | 76 | /** 77 | * get请求 78 | */ 79 | public void onGet(View view) { 80 | Observable observable = HttpRequest.getNetService().get(0, 10); 81 | observable.subscribeOn(Schedulers.io()) 82 | .observeOn(AndroidSchedulers.mainThread()) 83 | .doOnDispose(new Action() { 84 | @Override 85 | public void run() throws Exception { 86 | Log.e("yxw","取消订阅2"); 87 | } 88 | }) 89 | .as(AutoDispose.autoDisposable( 90 | AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_PAUSE)))//OnDestory时自动解绑 91 | .subscribe(new Observer() { 92 | @Override 93 | public void onSubscribe(@NonNull Disposable d) { 94 | Log.e("yxw", "onGet2 onSubscribe "); 95 | } 96 | 97 | @Override 98 | public void onNext(@NonNull HomeInfoV5 homeInfoV5) { 99 | Log.e("yxw", "onGet2 onNext " + homeInfoV5.getMsg()); 100 | } 101 | 102 | @Override 103 | public void onError(@NonNull Throwable e) { 104 | Log.e("yxw", "onGet2 fail " + e.getMessage()); 105 | } 106 | 107 | @Override 108 | public void onComplete() { 109 | Log.e("yxw", "onGet2 onComplete "); 110 | } 111 | }); 112 | 113 | } 114 | 115 | } 116 | ~~~ 117 | #### POST请求如何区分表单跟JOSN,,这里我们抛弃了Retrofit的复杂度 118 | 例子如下:表单请求 119 | ~~~ 120 | @FORM 121 | @POST("https://bx-uat.bisinuolan.cn/api/login/mobile") 122 | Call postForm(@Param("mobile") String mobile, @Param("sms_code") String sms_code); 123 | ~~~ 124 | 注意2个注解 `@FORM` 跟`@Param` 我们舍弃了Retrofit的 `@Field` 跟`@FormUrlEncoded` 125 | `@FORM` 替换了`@FormUrlEncoded` 来区分是否表单 126 | `@Param` 替换了`@Field` , 127 | `@Param` 有个好处就是: 128 | 1、不管是表单请求还JSON请求,都是可以作为参数来传参 129 | 2、如果用来Json请求的话,他会作为json格式的最外层数据, 130 | 哎这个怎么解释呢。就是如果你用@Param("userId"),那么最终传参是 131 | ~~~ 132 | { 133 | "userId": "c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008" 134 | } 135 | ~~~ 136 | 137 | `@Body` 注解,可以这样传 138 | ~~~ 139 | /** 140 | * json 整串提交 141 | */ 142 | @POST("api/customer/v1/open/user/level/my") 143 | Call postJson2(@Body String json); 144 | 145 | /** 146 | * json 实体类提交 147 | */ 148 | @POST("api/customer/v1/open/user/level/my") 149 | Call postJson(@Body LoginBuild json); 150 | ~~~ 151 | `@Body` 注解跟Retrofit 注解一样,拥有一个功能,那是`转换器`,在添加转换器的时候,我们会通过 `@Body` 注解,判断当前是什么类型,然后通过类型,进行转换你想要的数据。。 152 | 上面的那个实体类提交就是这个原理,判断是Object类型的话,然后将Object类型转换为JSON格式进行提交。 153 | 那么你就可以定义你们公司需要啥类型,做啥处理。反正你们自己想。 154 | 155 | *** 156 | 157 | #### 配置。这个是跟Retrofit是一样的。。 158 | 159 | OkHttpClient client = new OkHttpClient 160 | .Builder() 161 | .connectTimeout(15, TimeUnit.SECONDS)//连接超时时间 162 | .readTimeout(15, TimeUnit.SECONDS)//读取超时时间 163 | .writeTimeout(15, TimeUnit.SECONDS)//写入超时时间 164 | .retryOnConnectionFailure(false)//连接不上是否重连,false不重连 165 | .hostnameVerifier(new TrustAllHostnameVerifier())//校验名称,这个对象就是信任所有的主机,也就是信任所有https的请求 166 | .sslSocketFactory(SslUtils.getSslSocketFactory().sSLSocketFactory, SslUtils.getSslSocketFactory().trustManager) 167 | .build(); 168 | HttpManager.Builder() 169 | .baseUrl("https://bxapi.bisinuolan.cn/") 170 | .addConverterFactory(GsonConverterFactories.create())//FastJson转换器、可以替换成Gson 171 | .addCallAdapterFactory(Rxjava2CallAdapterFactories.create())//Rxjava2适配器,不配置有自带Call适配器 172 | .client(client) 173 | .build(); 174 | 175 | #### 出如何初始呢,NetService (类名是随便定义的)接口呢,那就是下面那个 176 | ~~~ 177 | public class HttpRequest { 178 | 179 | private static NetService netService; 180 | 181 | public static NetService getNetService() { 182 | try { 183 | if (netService == null) { 184 | synchronized (HttpRequest.class) { 185 | if (netService == null) { 186 | netService = (NetService) Class.forName(HttpManager.getImplName(NetService.class)) 187 | .getConstructor().newInstance(); 188 | } 189 | } 190 | } 191 | } catch (Exception e) { 192 | e.printStackTrace(); 193 | } 194 | return netService; 195 | } 196 | } 197 | 198 | ~~~ 199 | 200 | 然后使用的时候就是直接 201 | HttpRequest.getNetService().get(0, 10); 202 | *** 203 | ### github [点击跳转](https://github.com/yanxuwen/XRetrofit) 204 | ### 如果你喜欢就去 github 帮我star下,非常感谢o(∩_∩)o~~~ 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /XRetrofit/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/ 38 | 39 | # Keystore files 40 | *.jks 41 | 42 | # External native build folder generated in Android Studio 2.2 and later 43 | .externalNativeBuild -------------------------------------------------------------------------------- /XRetrofit/Could: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yanxuwen/XRetrofit/5dff429dfd666c4861d3b714640a12251ac47d1c/XRetrofit/Could -------------------------------------------------------------------------------- /XRetrofit/annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /XRetrofit/annotations/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | ext { 4 | bintrayName = 'annotations' 5 | artifact = bintrayName 6 | libraryName = 'xretrofit-annotations' 7 | libraryDescription = 'this is a xretrofit-annotations' 8 | libraryVersion = main_version 9 | } 10 | compileJava { 11 | sourceCompatibility = '1.8' 12 | targetCompatibility = '1.8' 13 | } 14 | 15 | dependencies { 16 | } 17 | 18 | //apply from: '../install.gradle' 19 | //apply from: '../bintray.gradle' 20 | apply from: '../jitpack.gradle' 21 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/DELETE.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface DELETE { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/DOWNLOAD.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface DOWNLOAD { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/FORM.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * 标记是否是表单提交 16 | */ 17 | @Documented 18 | @Target({ElementType.METHOD}) 19 | @Retention(RetentionPolicy.CLASS) 20 | public @interface FORM { 21 | } 22 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/GET.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface GET { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/Headers.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface Headers { 18 | String[] value(); 19 | boolean encoded() default false; 20 | } 21 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/POST.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface POST { 18 | String value() default ""; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/PUT.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface PUT { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/UPLOAD.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.method; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.METHOD}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface UPLOAD { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Body.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.PARAMETER}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface Body { 18 | } 19 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/FilePath.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | //用于文件上传用的路径 15 | //支持 File String List List 16 | @Documented 17 | @Target({ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.CLASS) 19 | public @interface FilePath { 20 | } 21 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Header.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Retention(RetentionPolicy.CLASS) 16 | @Target({ElementType.PARAMETER}) 17 | public @interface Header { 18 | String value(); 19 | boolean encoded() default false; 20 | } 21 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Param.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.PARAMETER}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface Param { 18 | String value(); 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Path.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Retention(RetentionPolicy.CLASS) 16 | @Target({ElementType.PARAMETER}) 17 | public @interface Path { 18 | String value(); 19 | 20 | boolean encoded() default false; 21 | } 22 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Query.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.yanxuwen.xretrofit_annotations.annotation.param; 7 | 8 | import java.lang.annotation.Documented; 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Documented 15 | @Target({ElementType.PARAMETER}) 16 | @Retention(RetentionPolicy.CLASS) 17 | public @interface Query { 18 | String value(); 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/service/NetServiceClass.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit_annotations.annotation.service; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target({ElementType.TYPE}) 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface NetServiceClass { 11 | String value() default ""; 12 | } 13 | -------------------------------------------------------------------------------- /XRetrofit/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /XRetrofit/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion build_versions.target_sdk 5 | buildToolsVersion build_versions.build_tools 6 | defaultConfig { 7 | applicationId "com.yanxuwen.myhttpservice" 8 | minSdkVersion build_versions.min_sdk 9 | targetSdkVersion build_versions.target_sdk 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | multiDexEnabled true 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | repositories { 22 | flatDir { dirs 'libs' } 23 | } 24 | 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | 30 | } 31 | //自动导入libs目录下的aar文件 32 | fileTree(dir: 'libs', include: '**/*.aar').each { File file -> 33 | dependencies.add("implementation", [name: file.name.lastIndexOf('.').with { 34 | it != -1 ? file.name[0.. 2 | 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit; 2 | 3 | import android.Manifest; 4 | import android.os.Bundle; 5 | import android.os.Environment; 6 | import android.os.Looper; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.widget.Toast; 10 | 11 | import androidx.appcompat.app.AppCompatActivity; 12 | import androidx.lifecycle.Lifecycle; 13 | 14 | import com.tbruyelle.rxpermissions2.Permission; 15 | import com.tbruyelle.rxpermissions2.RxPermissions; 16 | import com.uber.autodispose.AutoDispose; 17 | import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider; 18 | import com.xretrofit.call.Call; 19 | import com.xretrofit.call.ProgressCall; 20 | import com.yanxuwen.xretrofit.bean.HomeInfoV5; 21 | import com.yanxuwen.xretrofit.bean.LoginBuild; 22 | import com.yanxuwen.xretrofit.callback.MyCallBack; 23 | import com.yanxuwen.xretrofit.callback.MyProgressCallBack; 24 | import com.yanxuwen.xretrofit.http.HttpRequest; 25 | 26 | import io.reactivex.Observable; 27 | import io.reactivex.Observer; 28 | import io.reactivex.android.schedulers.AndroidSchedulers; 29 | import io.reactivex.annotations.NonNull; 30 | import io.reactivex.disposables.Disposable; 31 | import io.reactivex.functions.Action; 32 | import io.reactivex.functions.Consumer; 33 | import io.reactivex.schedulers.Schedulers; 34 | 35 | public class MainActivity extends AppCompatActivity { 36 | 37 | @Override 38 | protected void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | setContentView(R.layout.activity_main); 41 | } 42 | 43 | public boolean isMainThread() { 44 | return Looper.getMainLooper().getThread() == Thread.currentThread(); 45 | } 46 | 47 | /** 48 | * get请求 49 | */ 50 | public void onGet(View view) { 51 | Observable observable = HttpRequest.getNetService().get(0, 10); 52 | observable 53 | .as(RxSchedulers.applySchedulers(this)) 54 | .subscribe(new Observer() { 55 | @Override 56 | public void onSubscribe(@NonNull Disposable d) { 57 | Log.e("yxw", isMainThread() +" onGet2 onSubscribe "); 58 | } 59 | 60 | @Override 61 | public void onNext(@NonNull HomeInfoV5 homeInfoV5) { 62 | Log.e("yxw", isMainThread() + " onGet2 onNext " + homeInfoV5.getMsg()); 63 | } 64 | 65 | @Override 66 | public void onError(@NonNull Throwable e) { 67 | Log.e("yxw", "onGet2 fail " + e.getMessage()); 68 | } 69 | 70 | @Override 71 | public void onComplete() { 72 | Log.e("yxw", isMainThread() + " onGet2 onComplete "); 73 | } 74 | }); 75 | 76 | } 77 | 78 | /** 79 | * get请求(URL中带有参数,也支持post) 80 | */ 81 | public void onGet2(View view) { 82 | Call call = HttpRequest.getNetService().get("detail-v2", 0, 10); 83 | call.enqueue(new MyCallBack(this) { 84 | 85 | @Override 86 | public void success(HomeInfoV5 s) { 87 | Log.e("yxw", "onGet:" + s.getMsg()); 88 | } 89 | 90 | @Override 91 | public void fail(String msg) { 92 | Log.e("yxw", "onGet:" + msg); 93 | } 94 | 95 | @Override 96 | public void cancel() { 97 | Log.e("yxw", "cancel"); 98 | } 99 | }); 100 | 101 | } 102 | 103 | /** 104 | * 表单提交 105 | */ 106 | public void postForm(View view) { 107 | Call call = HttpRequest.getNetService().postForm("19906058322", "10960"); 108 | call.enqueue(new MyCallBack() { 109 | @Override 110 | public void success(String s) { 111 | Log.e("yxw", "postForm:" + s); 112 | } 113 | 114 | @Override 115 | public void fail(String msg) { 116 | Log.e("yxw", "postForm:" + msg); 117 | } 118 | }); 119 | } 120 | 121 | /** 122 | * json提交 123 | */ 124 | public void postJson(View view) { 125 | String userId = "c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008"; 126 | Call call = HttpRequest.getNetService().postJson(userId); 127 | call.enqueue(new MyCallBack() { 128 | @Override 129 | public void success(String s) { 130 | Log.e("yxw", "postJson:" + s); 131 | } 132 | 133 | @Override 134 | public void fail(String msg) { 135 | Log.e("yxw", "postJson:" + msg); 136 | } 137 | }); 138 | } 139 | 140 | /** 141 | * json 整串提交 142 | */ 143 | public void postJson2(View view) { 144 | String json = "{\n" + 145 | "\t\"userId\": \"c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008\"\n" + 146 | "}"; 147 | Call call = HttpRequest.getNetService().postJson2(json); 148 | call.enqueue(new MyCallBack() { 149 | @Override 150 | public void success(String s) { 151 | Log.e("yxw", "postJson2:" + s); 152 | } 153 | 154 | @Override 155 | public void fail(String msg) { 156 | Log.e("yxw", "postJson2:" + msg); 157 | } 158 | }); 159 | } 160 | 161 | /** 162 | * json 整串提交 163 | */ 164 | public void postJson3(View view) { 165 | LoginBuild mLoginBuild = new LoginBuild(); 166 | mLoginBuild.setUserId("c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008"); 167 | Call call = HttpRequest.getNetService().postJson(mLoginBuild); 168 | call.enqueue(new MyCallBack() { 169 | @Override 170 | public void success(String s) { 171 | Log.e("yxw", "postJson2:" + s); 172 | } 173 | 174 | @Override 175 | public void fail(String msg) { 176 | Log.e("yxw", "postJson2:" + msg); 177 | } 178 | }); 179 | } 180 | 181 | /** 182 | * put 提交 183 | */ 184 | public void onPut(View view) { 185 | Call call = HttpRequest.getNetService().put("header", "测试", "signature", "area"); 186 | call.enqueue(new MyCallBack() { 187 | @Override 188 | public void success(String s) { 189 | Log.e("yxw", "onPut :" + s); 190 | } 191 | 192 | @Override 193 | public void fail(String msg) { 194 | Log.e("yxw", "onPut fail :" + msg); 195 | } 196 | }); 197 | } 198 | 199 | /** 200 | * delete 提交 201 | */ 202 | public void onDelete(View view) { 203 | Call call = HttpRequest.getNetService().delete("header", "123231"); 204 | call.enqueue(new MyCallBack() { 205 | @Override 206 | public void success(String s) { 207 | Log.e("yxw", "onDelete :" + s); 208 | } 209 | 210 | @Override 211 | public void fail(String msg) { 212 | Log.e("yxw", "onDelete fail :" + msg); 213 | } 214 | }); 215 | } 216 | 217 | public void onDownload(View v) { 218 | //先权限申请,在请求 219 | RxPermissions rxPermissions = new RxPermissions(this); 220 | rxPermissions.requestEach( 221 | Manifest.permission.WRITE_EXTERNAL_STORAGE) 222 | .subscribe(new Consumer() { 223 | @Override 224 | public void accept(Permission permission) throws Exception { 225 | if (permission.granted) { 226 | String path = Environment.getExternalStorageDirectory().toString() + "/测试/text2.apk";//获取目录 227 | ProgressCall call = HttpRequest.getNetService().download(path); 228 | call.enqueue(new MyProgressCallBack() { 229 | @Override 230 | public void onProgress(float progress) { 231 | Log.e("yxw", "onDownload progress :" + progress); 232 | } 233 | 234 | @Override 235 | public void success(String s) { 236 | Log.e("yxw", "onDownload :" + s); 237 | } 238 | 239 | @Override 240 | public void fail(String msg) { 241 | Log.e("yxw", "onDownload fail :" + msg); 242 | } 243 | }); 244 | } else { 245 | Toast.makeText(MainActivity.this, "请打开存储权限", Toast.LENGTH_SHORT).show(); 246 | } 247 | } 248 | }); 249 | } 250 | 251 | public void onUpload(View v) { 252 | // //先权限申请,在请求 253 | RxPermissions rxPermissions = new RxPermissions(this); 254 | rxPermissions.requestEach( 255 | Manifest.permission.WRITE_EXTERNAL_STORAGE) 256 | .subscribe(new Consumer() { 257 | @Override 258 | public void accept(Permission permission) throws Exception { 259 | if (permission.granted) { 260 | //允许权限 261 | String path = Environment.getExternalStorageDirectory().toString() + "/测试/测试.mp4";//获取跟目录 262 | ProgressCall call = HttpRequest.getNetService().upload(path, true); 263 | call.enqueue(new MyProgressCallBack() { 264 | @Override 265 | public void success(String s) { 266 | Log.e("yxw", "onUpload :" + s); 267 | } 268 | 269 | @Override 270 | public void fail(String msg) { 271 | Log.e("yxw", "onUpload2 fail:" + msg); 272 | } 273 | 274 | @Override 275 | public void onProgress(float progress) { 276 | Log.e("yxw", "onUpload2 progress:" + progress); 277 | } 278 | }); 279 | } else { 280 | Toast.makeText(MainActivity.this, "请打开存储权限", Toast.LENGTH_SHORT).show(); 281 | } 282 | } 283 | }); 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit; 2 | 3 | import android.app.Application; 4 | 5 | import com.xretrofit.HttpManager; 6 | import com.xretrofit.okhttp.SslUtils; 7 | import com.yanxuwen.xretrofit.converter.GsonConverterFactories; 8 | import com.yanxuwen.xretrofit.converter.Rxjava2CallAdapterFactories; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import javax.net.ssl.HostnameVerifier; 13 | import javax.net.ssl.SSLSession; 14 | 15 | import okhttp3.OkHttpClient; 16 | 17 | public class MyApplication extends Application { 18 | @Override 19 | public void onCreate() { 20 | super.onCreate(); 21 | init(); 22 | } 23 | 24 | public void init() { 25 | 26 | OkHttpClient client = new OkHttpClient 27 | .Builder() 28 | .connectTimeout(15, TimeUnit.SECONDS)//连接超时时间 29 | .readTimeout(15, TimeUnit.SECONDS)//读取超时时间 30 | .writeTimeout(15, TimeUnit.SECONDS)//写入超时时间 31 | .retryOnConnectionFailure(false)//连接不上是否重连,false不重连 32 | .hostnameVerifier(new TrustAllHostnameVerifier())//校验名称,这个对象就是信任所有的主机,也就是信任所有https的请求 33 | .sslSocketFactory(SslUtils.getSslSocketFactory().sSLSocketFactory, SslUtils.getSslSocketFactory().trustManager) 34 | .build(); 35 | HttpManager.Builder() 36 | .baseUrl("https://bxapi.bisinuolan.cn/") 37 | .addConverterFactory(GsonConverterFactories.create())//FastJson转换器、可以替换成Gson 38 | .addCallAdapterFactory(Rxjava2CallAdapterFactories.create())//Rxjava2适配器,不配置有自带Call适配器 39 | .client(client) 40 | .build(); 41 | } 42 | 43 | /** 44 | * 信任所有的服务器,返回true 45 | */ 46 | private static class TrustAllHostnameVerifier implements HostnameVerifier { 47 | @Override 48 | public boolean verify(String hostname, SSLSession session) { 49 | return true; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/RxSchedulers.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit; 2 | 3 | import androidx.lifecycle.Lifecycle; 4 | import androidx.lifecycle.LifecycleOwner; 5 | 6 | import com.uber.autodispose.AutoDispose; 7 | import com.uber.autodispose.ObservableSubscribeProxy; 8 | import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider; 9 | 10 | import io.reactivex.Observable; 11 | import io.reactivex.ObservableConverter; 12 | import io.reactivex.android.schedulers.AndroidSchedulers; 13 | import io.reactivex.annotations.NonNull; 14 | import io.reactivex.schedulers.Schedulers; 15 | 16 | /** 17 | * @author bsnl_yanxuwen 18 | * @date 2021/3/19 10:52 19 | * Description : 20 | */ 21 | public class RxSchedulers { 22 | public static ObservableConverter applySchedulers(LifecycleOwner owner) { 23 | return new ObservableConverter() { 24 | @NonNull 25 | @Override 26 | public ObservableSubscribeProxy apply(@NonNull Observable upstream) { 27 | return upstream 28 | .subscribeOn(Schedulers.io()) 29 | .observeOn(AndroidSchedulers.mainThread()) 30 | .as(AutoDispose.autoDisposable( 31 | AndroidLifecycleScopeProvider.from(owner, Lifecycle.Event.ON_DESTROY))); 32 | } 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/bean/HomeInfoV5.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.bean; 2 | 3 | /** 4 | * @author bsnl_yanxuwen 5 | * @date 2021/2/19 9:21 6 | * Description : 7 | */ 8 | public class HomeInfoV5 { 9 | 10 | private String msg; 11 | 12 | public String getMsg() { 13 | return msg; 14 | } 15 | 16 | public void setMsg(String msg) { 17 | this.msg = msg; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/bean/LoginBuild.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.bean; 2 | 3 | public class LoginBuild { 4 | 5 | /** 6 | * password : “123456” 7 | * mobile : “15060568265” 8 | */ 9 | 10 | private String userId; 11 | private String msg; 12 | 13 | public String getUserId() { 14 | return userId; 15 | } 16 | 17 | public void setUserId(String userId) { 18 | this.userId = userId; 19 | } 20 | 21 | public String getMsg() { 22 | return msg; 23 | } 24 | 25 | public void setMsg(String msg) { 26 | this.msg = msg; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/MyCallBack.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.callback; 2 | 3 | import android.util.Log; 4 | 5 | import androidx.fragment.app.FragmentActivity; 6 | import androidx.lifecycle.Lifecycle; 7 | import androidx.lifecycle.LifecycleObserver; 8 | import androidx.lifecycle.OnLifecycleEvent; 9 | 10 | import com.xretrofit.Response; 11 | import com.xretrofit.call.Call; 12 | import com.xretrofit.callback.CallBack; 13 | 14 | /** 15 | * @author bsnl_yanxuwen 16 | * @date 2021/2/5 11:19 17 | * Description : 18 | */ 19 | public abstract class MyCallBack implements CallBack { 20 | 21 | private FragmentActivity activity; 22 | 23 | public MyCallBack() { 24 | } 25 | 26 | public MyCallBack(FragmentActivity activity) { 27 | this.activity = activity; 28 | } 29 | 30 | @Override 31 | public void onStart(Call call) { 32 | if (activity != null) { 33 | activity.getLifecycle().addObserver(new LifecycleObserver() { 34 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 35 | public void onDestroy() { 36 | Log.e("yxw", "????取消请求"); 37 | call.cancel(); 38 | } 39 | 40 | }); 41 | } 42 | } 43 | 44 | @Override 45 | public final void onSuccess(Call call, Response response) { 46 | if (response.errorBody() != null) { 47 | fail("网络异常"); 48 | return; 49 | } 50 | success(response.body()); 51 | 52 | } 53 | 54 | @Override 55 | public final void onFail(Call call, Throwable e) { 56 | if (call.isCanceled()){ 57 | cancel(); 58 | } else { 59 | fail(ServerException.handleException(e)); 60 | } 61 | } 62 | 63 | 64 | public abstract void success(T t); 65 | 66 | public abstract void fail(String msg); 67 | 68 | public void cancel(){ 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/MyProgressCallBack.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.callback; 2 | 3 | import com.xretrofit.Response; 4 | import com.xretrofit.call.Call; 5 | import com.xretrofit.callback.ProgressCallBack; 6 | 7 | public abstract class MyProgressCallBack extends ProgressCallBack { 8 | 9 | @Override 10 | public void onStart(Call call) { 11 | 12 | } 13 | 14 | @Override 15 | public final void onSuccess(Call call, Response response) { 16 | if (response.errorBody() != null) { 17 | fail("网络异常"); 18 | return; 19 | } 20 | success(response.body()); 21 | 22 | } 23 | 24 | @Override 25 | public final void onFail(Call call, Throwable e) { 26 | fail(ServerException.handleException(e)); 27 | } 28 | 29 | 30 | public abstract void success(T t); 31 | 32 | public abstract void fail(String msg); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/ServerException.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.callback; 2 | 3 | import org.apache.http.conn.ConnectTimeoutException; 4 | import org.json.JSONException; 5 | 6 | import java.io.NotSerializableException; 7 | import java.net.ConnectException; 8 | import java.net.SocketTimeoutException; 9 | import java.net.UnknownHostException; 10 | import java.text.ParseException; 11 | 12 | public class ServerException { 13 | 14 | public static String handleException(Throwable e) { 15 | String msg = e.getMessage(); 16 | if (e instanceof SocketTimeoutException) { 17 | msg = "网络连接超时,请检查网络"; 18 | } else if (e instanceof ConnectException) { 19 | msg = "网络异常,请检查网络"; 20 | } else if (e instanceof ConnectTimeoutException) { 21 | msg = "网络连接超时,请检查网络"; 22 | } else if (e instanceof UnknownHostException) { 23 | msg = "网络异常,请检查网络"; 24 | } else if (e instanceof NullPointerException) { 25 | msg = "空指针异常"; 26 | } else if (e instanceof javax.net.ssl.SSLHandshakeException) { 27 | msg = "证书验证失败"; 28 | } else if (e instanceof ClassCastException) { 29 | msg = "类型转换错误"; 30 | } else if (/*e instanceof JsonParseException ||*/ 31 | e instanceof JSONException || 32 | e instanceof com.alibaba.fastjson.JSONException || 33 | /*e instanceof JsonSerializer ||*/ 34 | e instanceof NotSerializableException || 35 | e instanceof ParseException) { 36 | msg = "解析错误"; 37 | } 38 | return msg; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonConverterFactories.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.converter; 2 | 3 | import com.xretrofit.converter.Converter; 4 | 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | import okhttp3.RequestBody; 10 | import okhttp3.ResponseBody; 11 | 12 | /** 13 | * @author bsnl_yanxuwen 14 | * @date 2021/2/4 15:46 15 | * Description : 16 | * 接口数据转换器 17 | * fastjson转换器 18 | */ 19 | public class GsonConverterFactories extends Converter.Factory { 20 | 21 | public static GsonConverterFactories create() { 22 | return new GsonConverterFactories(); 23 | } 24 | 25 | @Nullable 26 | @Override 27 | public Converter requestBodyConverter(Type request, Type requestParamType) { 28 | if (requestParamType instanceof Object) { 29 | return new GsonRequestConverter(); 30 | } 31 | return null; 32 | } 33 | 34 | @Nullable 35 | @Override 36 | public Converter responseBodyConverter(Type request, Type responseType) { 37 | Class rawType = getRawType(responseType); 38 | if (rawType instanceof Object) { 39 | return new GsonResponseConverter(responseType); 40 | } 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonRequestConverter.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.converter; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.xretrofit.converter.Converter; 5 | 6 | import okhttp3.MediaType; 7 | import okhttp3.RequestBody; 8 | 9 | /** 10 | * @author bsnl_yanxuwen 11 | * @date 2021/2/5 16:00 12 | * Description : 13 | * 请求参数数据转换 14 | */ 15 | class GsonRequestConverter implements Converter { 16 | private static final MediaType JSON = MediaType.parse("application/json;charset=utf-8"); 17 | 18 | 19 | @Override 20 | public RequestBody convert(T value) throws Exception { 21 | RequestBody requestBody = RequestBody.create(JSON, JSONObject.toJSONString(value)); 22 | return requestBody; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonResponseConverter.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.converter; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.xretrofit.converter.Converter; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | import okhttp3.ResponseBody; 9 | 10 | /** 11 | * @author bsnl_yanxuwen 12 | * @date 2021/2/4 17:09 13 | * Description : 14 | * 请求结果数据转换 15 | * Gson操作 16 | */ 17 | public class GsonResponseConverter implements Converter { 18 | 19 | private Type responseType; 20 | 21 | protected GsonResponseConverter(Type responseType){ 22 | this.responseType = responseType; 23 | } 24 | 25 | 26 | @Override 27 | public T convert(ResponseBody value) throws Exception { 28 | String responseStr = value.string(); 29 | return (T) JSONObject.parseObject(responseStr,responseType); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/Rxjava2CallAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.converter; 2 | 3 | import com.xretrofit.CallAdapter.CallAdapter; 4 | import com.xretrofit.HttpException; 5 | import com.xretrofit.Response; 6 | import com.xretrofit.call.Call; 7 | 8 | import java.lang.ref.WeakReference; 9 | import java.lang.reflect.Type; 10 | 11 | import io.reactivex.Observable; 12 | import io.reactivex.Observer; 13 | import io.reactivex.disposables.Disposable; 14 | import io.reactivex.exceptions.CompositeException; 15 | import io.reactivex.exceptions.Exceptions; 16 | import io.reactivex.plugins.RxJavaPlugins; 17 | 18 | /** 19 | * @author bsnl_yanxuwen 20 | * @date 2021/2/8 10:19 21 | * Description : 22 | * rxjava 适配器 23 | */ 24 | class Rxjava2CallAdapter implements CallAdapter { 25 | 26 | private Type responseType; 27 | 28 | protected Rxjava2CallAdapter(Type responseType) { 29 | this.responseType = responseType; 30 | } 31 | 32 | 33 | @Override 34 | public Type responseType() { 35 | return responseType; 36 | } 37 | 38 | 39 | @Override 40 | public Observable adapt(Call call) { 41 | Observable observable = new CallExecuteObservable(call); 42 | return observable; 43 | } 44 | 45 | final class CallExecuteObservable extends Observable { 46 | private final Call call; 47 | 48 | 49 | CallExecuteObservable(Call call) { 50 | this.call = call; 51 | 52 | } 53 | 54 | @Override 55 | protected void subscribeActual(Observer observer) { 56 | CallDisposable disposable = new CallDisposable(call); 57 | observer.onSubscribe(disposable); 58 | Response response = null; 59 | try { 60 | response = call.execute(); 61 | if (response.isSuccessful()) { 62 | observer.onNext((T) response.body()); 63 | } else { 64 | Throwable t = new HttpException(response); 65 | try { 66 | observer.onError(t); 67 | } catch (Throwable inner) { 68 | Exceptions.throwIfFatal(inner); 69 | RxJavaPlugins.onError(new CompositeException(t, inner)); 70 | } 71 | } 72 | } catch (Throwable t) { 73 | Exceptions.throwIfFatal(t); 74 | if (!disposable.isDisposed()) { 75 | try { 76 | observer.onError(t); 77 | } catch (Throwable inner) { 78 | Exceptions.throwIfFatal(inner); 79 | RxJavaPlugins.onError(new CompositeException(t, inner)); 80 | } 81 | } 82 | } 83 | observer.onComplete(); 84 | } 85 | 86 | } 87 | 88 | 89 | private static final class CallDisposable implements Disposable { 90 | private volatile boolean disposed; 91 | private WeakReference weakCall; 92 | 93 | CallDisposable(Call call) { 94 | weakCall = new WeakReference<>(call); 95 | 96 | } 97 | 98 | @Override 99 | public void dispose() { 100 | disposed = true; 101 | if (weakCall != null) { 102 | weakCall.get().cancel(); 103 | } 104 | } 105 | 106 | @Override 107 | public boolean isDisposed() { 108 | return disposed; 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/Rxjava2CallAdapterFactories.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.converter; 2 | 3 | import com.xretrofit.CallAdapter.CallAdapter; 4 | import com.xretrofit.utils.Utils; 5 | 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.lang.reflect.Type; 9 | 10 | import io.reactivex.Observable; 11 | 12 | /** 13 | * @author bsnl_yanxuwen 14 | * @date 2021/2/4 15:46 15 | * Description : 16 | * rxjava2 适配器 17 | */ 18 | public class Rxjava2CallAdapterFactories extends CallAdapter.Factory { 19 | 20 | public static Rxjava2CallAdapterFactories create() { 21 | return new Rxjava2CallAdapterFactories(); 22 | } 23 | 24 | 25 | @Nullable 26 | @Override 27 | public CallAdapter get(Type returnType) { 28 | Class rawType = getRawType(returnType); 29 | final Type responseType = Utils.getCallResponseType(returnType); 30 | if (rawType == Observable.class) { 31 | return new Rxjava2CallAdapter(responseType); 32 | } 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/http/HttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.http; 2 | 3 | import com.xretrofit.HttpManager; 4 | 5 | public class HttpRequest { 6 | 7 | private static NetService netService; 8 | 9 | public static NetService getNetService() { 10 | try { 11 | if (netService == null) { 12 | synchronized (HttpRequest.class) { 13 | if (netService == null) { 14 | netService = (NetService) Class.forName(HttpManager.getImplName(NetService.class)) 15 | .getConstructor().newInstance(); 16 | } 17 | } 18 | } 19 | } catch (Exception e) { 20 | e.printStackTrace(); 21 | } 22 | return netService; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/http/NetService.java: -------------------------------------------------------------------------------- 1 | package com.yanxuwen.xretrofit.http; 2 | 3 | import com.xretrofit.call.Call; 4 | import com.xretrofit.call.ProgressCall; 5 | import com.yanxuwen.xretrofit_annotations.annotation.method.DELETE; 6 | import com.yanxuwen.xretrofit_annotations.annotation.method.DOWNLOAD; 7 | import com.yanxuwen.xretrofit_annotations.annotation.method.FORM; 8 | import com.yanxuwen.xretrofit_annotations.annotation.method.GET; 9 | import com.yanxuwen.xretrofit_annotations.annotation.method.POST; 10 | import com.yanxuwen.xretrofit_annotations.annotation.method.PUT; 11 | import com.yanxuwen.xretrofit_annotations.annotation.method.UPLOAD; 12 | import com.yanxuwen.xretrofit_annotations.annotation.param.Body; 13 | import com.yanxuwen.xretrofit_annotations.annotation.param.FilePath; 14 | import com.yanxuwen.xretrofit_annotations.annotation.param.Header; 15 | import com.yanxuwen.xretrofit_annotations.annotation.param.Param; 16 | import com.yanxuwen.xretrofit_annotations.annotation.param.Path; 17 | import com.yanxuwen.xretrofit_annotations.annotation.param.Query; 18 | import com.yanxuwen.xretrofit_annotations.annotation.service.NetServiceClass; 19 | import com.yanxuwen.xretrofit.bean.HomeInfoV5; 20 | import com.yanxuwen.xretrofit.bean.LoginBuild; 21 | 22 | import io.reactivex.Observable; 23 | 24 | @NetServiceClass 25 | public interface NetService { 26 | /** 27 | * get 28 | */ 29 | @GET("api/manage-home/v5/home/detail-v2") 30 | Observable get(@Query("page") int page, @Query("limit") int limit); 31 | 32 | /** 33 | * get请求(URL中带有参数) 34 | */ 35 | @GET("api/manage-home/v5/home/{version}") 36 | Call get(@Path("version") String version, @Query("page") int page, @Query("limit") int limit); 37 | 38 | /** 39 | * 表单提交 40 | */ 41 | @FORM 42 | @POST("https://bx-uat.bisinuolan.cn/api/login/mobile") 43 | Call postForm(@Param("mobile") String mobile, @Param("sms_code") String sms_code); 44 | 45 | /** 46 | * json提交 47 | */ 48 | @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") 49 | Call postJson(@Param("userId") String userId); 50 | 51 | /** 52 | * json 整串提交 53 | */ 54 | @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") 55 | Call postJson2(@Body String json); 56 | 57 | /** 58 | * json 实体类提交 59 | */ 60 | @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") 61 | Call postJson(@Body LoginBuild json); 62 | 63 | /** 64 | * put 提交 65 | */ 66 | @PUT("http://api.sdwhcn.com:5056/v1/member") 67 | Call put(@Header("Authorization") String header, @Query("nickname") String nickname, @Query("signature") String signature, @Query("area") String area); 68 | 69 | /** 70 | * delete 提交 71 | */ 72 | @DELETE("http://api.sdwhcn.com:5056/v1/member_collect_article/{id}") 73 | Call delete(@Header("Authorization") String header, @Path("id") String id); 74 | 75 | /** 76 | * 77 | */ 78 | @DOWNLOAD("https://ztjyupdate.ztjy61.com/333897c77ec9a86605006679c7a4b418-ZTJY") 79 | ProgressCall download(@FilePath String file); 80 | 81 | /** 82 | * 多图上传 83 | */ 84 | @UPLOAD("https://bxuatapi.bisinuolan.cn/api/bsnl-oss/appUploadShot") 85 | ProgressCall upload(@FilePath String file, @Param("shot") boolean shot); 86 | 87 | } -------------------------------------------------------------------------------- /XRetrofit/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /XRetrofit/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 |