Repository: yanxuwen/okhttp Branch: master Commit: 5dff429dfd66 Files: 98 Total size: 149.3 KB Directory structure: gitextract_6p_2z26y/ ├── 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/ │ │ └── ic_launcher_background.xml │ ├── drawable-v24/ │ │ └── ic_launcher_foreground.xml │ ├── layout/ │ │ └── activity_main.xml │ ├── mipmap-anydpi-v26/ │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── 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/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.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 ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ #### 介绍 XRetrofit 是一个极致模仿Retrofit 的风格代码,代码没有Retrofit 复杂,简单易懂。 #### 支持`get`、`post`、`put`、`delete` 请求,这些使用都一样。 简化文件上传,跟下载 使用`@DOWNLOAD` 跟`@UPLOAD` 简化` post` 表单请求跟JOSN请求。 支持转换器,如果需要Gson的转换器,可以去demo那边去复制 支持适配器,内置跟Retrofit的`Call`,当然了String可以替换任意的类型,跟Retrofit一样 没有内置`Rxjava的适配器`,如果需要,自己去demo那边复制。 ##### 区别 `Retrofit` 属于运行时注解,通过动态代理生成一个代码 `XRetrofit` 属于编译时注解,通过APT生成代码,如果要学习APT,可以操作这篇文章[《带你了解APT》点击传送门](https://www.jianshu.com/p/00dce41e5d00) ##### 依赖, 只支持androidX,没有supper版本 ~~~ implementation 'com.yanxuwen.xretrofit:xretrofit:2.0.0' annotationProcessor 'com.yanxuwen.xretrofit:xretrofit-compiler:2.0.0' ~~~ ##### 依赖, 由于jcenter要跑路了,所以已迁移到jitpack ~~~ implementation 'com.github.yanxuwen:xretrofit:0.0.8' annotationProcessor 'com.github.yanxuwen.xretrofit:compiler:0.0.8' ~~~ #### 使用方法,跟Retrofit一样,要定义接口,唯一区别在于在类上面要添加注解`@NetServiceClass` #### 定义接口,该例子分别写了`Rxjava` 、`Call` 、`同步请求`的使用 ~~~ @NetServiceClass public interface NetService { /** * Rxjava 适配器 */ @GET("api/manage-home/v5/home/detail-v2") Observable get(@Query("page") int page, @Query("limit") int limit); /** * 自带Call 适配器 */ @GET("api/manage-home/v5/home/{version}") Call get(@Path("version") String version, @Query("page") int page, @Query("limit") int limit); /** * 同步请求 */ @GET("api/manage-home/v5/home/detail-v2") String get3(@Query("page") int page, @Query("limit") int limit); } ~~~ #### 执行请求,以Call 适配器为例子 ~~~ public void onGet2(View view) { Call call = HttpRequest.getNetService().get("detail-v2", 0, 10); call.enqueue(new MyCallBack(this) { @Override public void success(HomeInfoV5 s) { Log.e("yxw", "onGet:" + s.getMsg()); } @Override public void fail(String msg) { Log.e("yxw", "onGet:" + msg); } @Override public void cancel() { Log.e("yxw", "cancel"); } }); } ~~~ #### 执行请求,以Rxjava 适配器为例子 ~~~ /** * get请求 */ public void onGet(View view) { Observable observable = HttpRequest.getNetService().get(0, 10); observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnDispose(new Action() { @Override public void run() throws Exception { Log.e("yxw","取消订阅2"); } }) .as(AutoDispose.autoDisposable( AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_PAUSE)))//OnDestory时自动解绑 .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("yxw", "onGet2 onSubscribe "); } @Override public void onNext(@NonNull HomeInfoV5 homeInfoV5) { Log.e("yxw", "onGet2 onNext " + homeInfoV5.getMsg()); } @Override public void onError(@NonNull Throwable e) { Log.e("yxw", "onGet2 fail " + e.getMessage()); } @Override public void onComplete() { Log.e("yxw", "onGet2 onComplete "); } }); } } ~~~ #### POST请求如何区分表单跟JOSN,,这里我们抛弃了Retrofit的复杂度 例子如下:表单请求 ~~~ @FORM @POST("https://bx-uat.bisinuolan.cn/api/login/mobile") Call postForm(@Param("mobile") String mobile, @Param("sms_code") String sms_code); ~~~ 注意2个注解 `@FORM` 跟`@Param` 我们舍弃了Retrofit的 `@Field` 跟`@FormUrlEncoded` `@FORM` 替换了`@FormUrlEncoded` 来区分是否表单 `@Param` 替换了`@Field` , `@Param` 有个好处就是: 1、不管是表单请求还JSON请求,都是可以作为参数来传参 2、如果用来Json请求的话,他会作为json格式的最外层数据, 哎这个怎么解释呢。就是如果你用@Param("userId"),那么最终传参是 ~~~ { "userId": "c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008" } ~~~ `@Body` 注解,可以这样传 ~~~ /** * json 整串提交 */ @POST("api/customer/v1/open/user/level/my") Call postJson2(@Body String json); /** * json 实体类提交 */ @POST("api/customer/v1/open/user/level/my") Call postJson(@Body LoginBuild json); ~~~ `@Body` 注解跟Retrofit 注解一样,拥有一个功能,那是`转换器`,在添加转换器的时候,我们会通过 `@Body` 注解,判断当前是什么类型,然后通过类型,进行转换你想要的数据。。 上面的那个实体类提交就是这个原理,判断是Object类型的话,然后将Object类型转换为JSON格式进行提交。 那么你就可以定义你们公司需要啥类型,做啥处理。反正你们自己想。 *** #### 配置。这个是跟Retrofit是一样的。。 OkHttpClient client = new OkHttpClient .Builder() .connectTimeout(15, TimeUnit.SECONDS)//连接超时时间 .readTimeout(15, TimeUnit.SECONDS)//读取超时时间 .writeTimeout(15, TimeUnit.SECONDS)//写入超时时间 .retryOnConnectionFailure(false)//连接不上是否重连,false不重连 .hostnameVerifier(new TrustAllHostnameVerifier())//校验名称,这个对象就是信任所有的主机,也就是信任所有https的请求 .sslSocketFactory(SslUtils.getSslSocketFactory().sSLSocketFactory, SslUtils.getSslSocketFactory().trustManager) .build(); HttpManager.Builder() .baseUrl("https://bxapi.bisinuolan.cn/") .addConverterFactory(GsonConverterFactories.create())//FastJson转换器、可以替换成Gson .addCallAdapterFactory(Rxjava2CallAdapterFactories.create())//Rxjava2适配器,不配置有自带Call适配器 .client(client) .build(); #### 出如何初始呢,NetService (类名是随便定义的)接口呢,那就是下面那个 ~~~ public class HttpRequest { private static NetService netService; public static NetService getNetService() { try { if (netService == null) { synchronized (HttpRequest.class) { if (netService == null) { netService = (NetService) Class.forName(HttpManager.getImplName(NetService.class)) .getConstructor().newInstance(); } } } } catch (Exception e) { e.printStackTrace(); } return netService; } } ~~~ 然后使用的时候就是直接 HttpRequest.getNetService().get(0, 10); *** ### github [点击跳转](https://github.com/yanxuwen/XRetrofit) ### 如果你喜欢就去 github 帮我star下,非常感谢o(∩_∩)o~~~ ================================================ FILE: XRetrofit/.gitignore ================================================ # Built application files *.apk *.ap_ # Files for the ART/Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log # Android Studio Navigation editor temp files .navigation/ # Android Studio captures folder captures/ # Intellij *.iml .idea/ # Keystore files *.jks # External native build folder generated in Android Studio 2.2 and later .externalNativeBuild ================================================ FILE: XRetrofit/Could ================================================ ================================================ FILE: XRetrofit/annotations/.gitignore ================================================ /build ================================================ FILE: XRetrofit/annotations/build.gradle ================================================ apply plugin: 'java' ext { bintrayName = 'annotations' artifact = bintrayName libraryName = 'xretrofit-annotations' libraryDescription = 'this is a xretrofit-annotations' libraryVersion = main_version } compileJava { sourceCompatibility = '1.8' targetCompatibility = '1.8' } dependencies { } //apply from: '../install.gradle' //apply from: '../bintray.gradle' apply from: '../jitpack.gradle' ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/DELETE.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface DELETE { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/DOWNLOAD.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface DOWNLOAD { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/FORM.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 标记是否是表单提交 */ @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface FORM { } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/GET.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface GET { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/Headers.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface Headers { String[] value(); boolean encoded() default false; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/POST.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface POST { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/PUT.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface PUT { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/method/UPLOAD.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.method; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) public @interface UPLOAD { String value() default ""; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Body.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.CLASS) public @interface Body { } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/FilePath.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //用于文件上传用的路径 //支持 File String List List @Documented @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.CLASS) public @interface FilePath { } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Header.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Retention(RetentionPolicy.CLASS) @Target({ElementType.PARAMETER}) public @interface Header { String value(); boolean encoded() default false; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Param.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.CLASS) public @interface Param { String value(); } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Path.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Retention(RetentionPolicy.CLASS) @Target({ElementType.PARAMETER}) public @interface Path { String value(); boolean encoded() default false; } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/param/Query.java ================================================ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.yanxuwen.xretrofit_annotations.annotation.param; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.CLASS) public @interface Query { String value(); } ================================================ FILE: XRetrofit/annotations/src/main/java/com/yanxuwen/xretrofit_annotations/annotation/service/NetServiceClass.java ================================================ package com.yanxuwen.xretrofit_annotations.annotation.service; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.CLASS) public @interface NetServiceClass { String value() default ""; } ================================================ FILE: XRetrofit/app/.gitignore ================================================ /build ================================================ FILE: XRetrofit/app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion build_versions.target_sdk buildToolsVersion build_versions.build_tools defaultConfig { applicationId "com.yanxuwen.myhttpservice" minSdkVersion build_versions.min_sdk targetSdkVersion build_versions.target_sdk versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } repositories { flatDir { dirs 'libs' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } //自动导入libs目录下的aar文件 fileTree(dir: 'libs', include: '**/*.aar').each { File file -> dependencies.add("implementation", [name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0.. ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/MainActivity.java ================================================ package com.yanxuwen.xretrofit; import android.Manifest; import android.os.Bundle; import android.os.Environment; import android.os.Looper; import android.util.Log; import android.view.View; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.Lifecycle; import com.tbruyelle.rxpermissions2.Permission; import com.tbruyelle.rxpermissions2.RxPermissions; import com.uber.autodispose.AutoDispose; import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider; import com.xretrofit.call.Call; import com.xretrofit.call.ProgressCall; import com.yanxuwen.xretrofit.bean.HomeInfoV5; import com.yanxuwen.xretrofit.bean.LoginBuild; import com.yanxuwen.xretrofit.callback.MyCallBack; import com.yanxuwen.xretrofit.callback.MyProgressCallBack; import com.yanxuwen.xretrofit.http.HttpRequest; import io.reactivex.Observable; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.annotations.NonNull; import io.reactivex.disposables.Disposable; import io.reactivex.functions.Action; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public boolean isMainThread() { return Looper.getMainLooper().getThread() == Thread.currentThread(); } /** * get请求 */ public void onGet(View view) { Observable observable = HttpRequest.getNetService().get(0, 10); observable .as(RxSchedulers.applySchedulers(this)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("yxw", isMainThread() +" onGet2 onSubscribe "); } @Override public void onNext(@NonNull HomeInfoV5 homeInfoV5) { Log.e("yxw", isMainThread() + " onGet2 onNext " + homeInfoV5.getMsg()); } @Override public void onError(@NonNull Throwable e) { Log.e("yxw", "onGet2 fail " + e.getMessage()); } @Override public void onComplete() { Log.e("yxw", isMainThread() + " onGet2 onComplete "); } }); } /** * get请求(URL中带有参数,也支持post) */ public void onGet2(View view) { Call call = HttpRequest.getNetService().get("detail-v2", 0, 10); call.enqueue(new MyCallBack(this) { @Override public void success(HomeInfoV5 s) { Log.e("yxw", "onGet:" + s.getMsg()); } @Override public void fail(String msg) { Log.e("yxw", "onGet:" + msg); } @Override public void cancel() { Log.e("yxw", "cancel"); } }); } /** * 表单提交 */ public void postForm(View view) { Call call = HttpRequest.getNetService().postForm("19906058322", "10960"); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "postForm:" + s); } @Override public void fail(String msg) { Log.e("yxw", "postForm:" + msg); } }); } /** * json提交 */ public void postJson(View view) { String userId = "c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008"; Call call = HttpRequest.getNetService().postJson(userId); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "postJson:" + s); } @Override public void fail(String msg) { Log.e("yxw", "postJson:" + msg); } }); } /** * json 整串提交 */ public void postJson2(View view) { String json = "{\n" + "\t\"userId\": \"c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008\"\n" + "}"; Call call = HttpRequest.getNetService().postJson2(json); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "postJson2:" + s); } @Override public void fail(String msg) { Log.e("yxw", "postJson2:" + msg); } }); } /** * json 整串提交 */ public void postJson3(View view) { LoginBuild mLoginBuild = new LoginBuild(); mLoginBuild.setUserId("c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008"); Call call = HttpRequest.getNetService().postJson(mLoginBuild); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "postJson2:" + s); } @Override public void fail(String msg) { Log.e("yxw", "postJson2:" + msg); } }); } /** * put 提交 */ public void onPut(View view) { Call call = HttpRequest.getNetService().put("header", "测试", "signature", "area"); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "onPut :" + s); } @Override public void fail(String msg) { Log.e("yxw", "onPut fail :" + msg); } }); } /** * delete 提交 */ public void onDelete(View view) { Call call = HttpRequest.getNetService().delete("header", "123231"); call.enqueue(new MyCallBack() { @Override public void success(String s) { Log.e("yxw", "onDelete :" + s); } @Override public void fail(String msg) { Log.e("yxw", "onDelete fail :" + msg); } }); } public void onDownload(View v) { //先权限申请,在请求 RxPermissions rxPermissions = new RxPermissions(this); rxPermissions.requestEach( Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Consumer() { @Override public void accept(Permission permission) throws Exception { if (permission.granted) { String path = Environment.getExternalStorageDirectory().toString() + "/测试/text2.apk";//获取目录 ProgressCall call = HttpRequest.getNetService().download(path); call.enqueue(new MyProgressCallBack() { @Override public void onProgress(float progress) { Log.e("yxw", "onDownload progress :" + progress); } @Override public void success(String s) { Log.e("yxw", "onDownload :" + s); } @Override public void fail(String msg) { Log.e("yxw", "onDownload fail :" + msg); } }); } else { Toast.makeText(MainActivity.this, "请打开存储权限", Toast.LENGTH_SHORT).show(); } } }); } public void onUpload(View v) { // //先权限申请,在请求 RxPermissions rxPermissions = new RxPermissions(this); rxPermissions.requestEach( Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Consumer() { @Override public void accept(Permission permission) throws Exception { if (permission.granted) { //允许权限 String path = Environment.getExternalStorageDirectory().toString() + "/测试/测试.mp4";//获取跟目录 ProgressCall call = HttpRequest.getNetService().upload(path, true); call.enqueue(new MyProgressCallBack() { @Override public void success(String s) { Log.e("yxw", "onUpload :" + s); } @Override public void fail(String msg) { Log.e("yxw", "onUpload2 fail:" + msg); } @Override public void onProgress(float progress) { Log.e("yxw", "onUpload2 progress:" + progress); } }); } else { Toast.makeText(MainActivity.this, "请打开存储权限", Toast.LENGTH_SHORT).show(); } } }); } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/MyApplication.java ================================================ package com.yanxuwen.xretrofit; import android.app.Application; import com.xretrofit.HttpManager; import com.xretrofit.okhttp.SslUtils; import com.yanxuwen.xretrofit.converter.GsonConverterFactories; import com.yanxuwen.xretrofit.converter.Rxjava2CallAdapterFactories; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; import okhttp3.OkHttpClient; public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); init(); } public void init() { OkHttpClient client = new OkHttpClient .Builder() .connectTimeout(15, TimeUnit.SECONDS)//连接超时时间 .readTimeout(15, TimeUnit.SECONDS)//读取超时时间 .writeTimeout(15, TimeUnit.SECONDS)//写入超时时间 .retryOnConnectionFailure(false)//连接不上是否重连,false不重连 .hostnameVerifier(new TrustAllHostnameVerifier())//校验名称,这个对象就是信任所有的主机,也就是信任所有https的请求 .sslSocketFactory(SslUtils.getSslSocketFactory().sSLSocketFactory, SslUtils.getSslSocketFactory().trustManager) .build(); HttpManager.Builder() .baseUrl("https://bxapi.bisinuolan.cn/") .addConverterFactory(GsonConverterFactories.create())//FastJson转换器、可以替换成Gson .addCallAdapterFactory(Rxjava2CallAdapterFactories.create())//Rxjava2适配器,不配置有自带Call适配器 .client(client) .build(); } /** * 信任所有的服务器,返回true */ private static class TrustAllHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; } } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/RxSchedulers.java ================================================ package com.yanxuwen.xretrofit; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import com.uber.autodispose.AutoDispose; import com.uber.autodispose.ObservableSubscribeProxy; import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider; import io.reactivex.Observable; import io.reactivex.ObservableConverter; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.annotations.NonNull; import io.reactivex.schedulers.Schedulers; /** * @author bsnl_yanxuwen * @date 2021/3/19 10:52 * Description : */ public class RxSchedulers { public static ObservableConverter applySchedulers(LifecycleOwner owner) { return new ObservableConverter() { @NonNull @Override public ObservableSubscribeProxy apply(@NonNull Observable upstream) { return upstream .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .as(AutoDispose.autoDisposable( AndroidLifecycleScopeProvider.from(owner, Lifecycle.Event.ON_DESTROY))); } }; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/bean/HomeInfoV5.java ================================================ package com.yanxuwen.xretrofit.bean; /** * @author bsnl_yanxuwen * @date 2021/2/19 9:21 * Description : */ public class HomeInfoV5 { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/bean/LoginBuild.java ================================================ package com.yanxuwen.xretrofit.bean; public class LoginBuild { /** * password : “123456” * mobile : “15060568265” */ private String userId; private String msg; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/MyCallBack.java ================================================ package com.yanxuwen.xretrofit.callback; import android.util.Log; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import com.xretrofit.Response; import com.xretrofit.call.Call; import com.xretrofit.callback.CallBack; /** * @author bsnl_yanxuwen * @date 2021/2/5 11:19 * Description : */ public abstract class MyCallBack implements CallBack { private FragmentActivity activity; public MyCallBack() { } public MyCallBack(FragmentActivity activity) { this.activity = activity; } @Override public void onStart(Call call) { if (activity != null) { activity.getLifecycle().addObserver(new LifecycleObserver() { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onDestroy() { Log.e("yxw", "????取消请求"); call.cancel(); } }); } } @Override public final void onSuccess(Call call, Response response) { if (response.errorBody() != null) { fail("网络异常"); return; } success(response.body()); } @Override public final void onFail(Call call, Throwable e) { if (call.isCanceled()){ cancel(); } else { fail(ServerException.handleException(e)); } } public abstract void success(T t); public abstract void fail(String msg); public void cancel(){ } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/MyProgressCallBack.java ================================================ package com.yanxuwen.xretrofit.callback; import com.xretrofit.Response; import com.xretrofit.call.Call; import com.xretrofit.callback.ProgressCallBack; public abstract class MyProgressCallBack extends ProgressCallBack { @Override public void onStart(Call call) { } @Override public final void onSuccess(Call call, Response response) { if (response.errorBody() != null) { fail("网络异常"); return; } success(response.body()); } @Override public final void onFail(Call call, Throwable e) { fail(ServerException.handleException(e)); } public abstract void success(T t); public abstract void fail(String msg); } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/callback/ServerException.java ================================================ package com.yanxuwen.xretrofit.callback; import org.apache.http.conn.ConnectTimeoutException; import org.json.JSONException; import java.io.NotSerializableException; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.text.ParseException; public class ServerException { public static String handleException(Throwable e) { String msg = e.getMessage(); if (e instanceof SocketTimeoutException) { msg = "网络连接超时,请检查网络"; } else if (e instanceof ConnectException) { msg = "网络异常,请检查网络"; } else if (e instanceof ConnectTimeoutException) { msg = "网络连接超时,请检查网络"; } else if (e instanceof UnknownHostException) { msg = "网络异常,请检查网络"; } else if (e instanceof NullPointerException) { msg = "空指针异常"; } else if (e instanceof javax.net.ssl.SSLHandshakeException) { msg = "证书验证失败"; } else if (e instanceof ClassCastException) { msg = "类型转换错误"; } else if (/*e instanceof JsonParseException ||*/ e instanceof JSONException || e instanceof com.alibaba.fastjson.JSONException || /*e instanceof JsonSerializer ||*/ e instanceof NotSerializableException || e instanceof ParseException) { msg = "解析错误"; } return msg; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonConverterFactories.java ================================================ package com.yanxuwen.xretrofit.converter; import com.xretrofit.converter.Converter; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Type; import okhttp3.RequestBody; import okhttp3.ResponseBody; /** * @author bsnl_yanxuwen * @date 2021/2/4 15:46 * Description : * 接口数据转换器 * fastjson转换器 */ public class GsonConverterFactories extends Converter.Factory { public static GsonConverterFactories create() { return new GsonConverterFactories(); } @Nullable @Override public Converter requestBodyConverter(Type request, Type requestParamType) { if (requestParamType instanceof Object) { return new GsonRequestConverter(); } return null; } @Nullable @Override public Converter responseBodyConverter(Type request, Type responseType) { Class rawType = getRawType(responseType); if (rawType instanceof Object) { return new GsonResponseConverter(responseType); } return null; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonRequestConverter.java ================================================ package com.yanxuwen.xretrofit.converter; import com.alibaba.fastjson.JSONObject; import com.xretrofit.converter.Converter; import okhttp3.MediaType; import okhttp3.RequestBody; /** * @author bsnl_yanxuwen * @date 2021/2/5 16:00 * Description : * 请求参数数据转换 */ class GsonRequestConverter implements Converter { private static final MediaType JSON = MediaType.parse("application/json;charset=utf-8"); @Override public RequestBody convert(T value) throws Exception { RequestBody requestBody = RequestBody.create(JSON, JSONObject.toJSONString(value)); return requestBody; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/GsonResponseConverter.java ================================================ package com.yanxuwen.xretrofit.converter; import com.alibaba.fastjson.JSONObject; import com.xretrofit.converter.Converter; import java.lang.reflect.Type; import okhttp3.ResponseBody; /** * @author bsnl_yanxuwen * @date 2021/2/4 17:09 * Description : * 请求结果数据转换 * Gson操作 */ public class GsonResponseConverter implements Converter { private Type responseType; protected GsonResponseConverter(Type responseType){ this.responseType = responseType; } @Override public T convert(ResponseBody value) throws Exception { String responseStr = value.string(); return (T) JSONObject.parseObject(responseStr,responseType); } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/Rxjava2CallAdapter.java ================================================ package com.yanxuwen.xretrofit.converter; import com.xretrofit.CallAdapter.CallAdapter; import com.xretrofit.HttpException; import com.xretrofit.Response; import com.xretrofit.call.Call; import java.lang.ref.WeakReference; import java.lang.reflect.Type; import io.reactivex.Observable; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.plugins.RxJavaPlugins; /** * @author bsnl_yanxuwen * @date 2021/2/8 10:19 * Description : * rxjava 适配器 */ class Rxjava2CallAdapter implements CallAdapter { private Type responseType; protected Rxjava2CallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public Observable adapt(Call call) { Observable observable = new CallExecuteObservable(call); return observable; } final class CallExecuteObservable extends Observable { private final Call call; CallExecuteObservable(Call call) { this.call = call; } @Override protected void subscribeActual(Observer observer) { CallDisposable disposable = new CallDisposable(call); observer.onSubscribe(disposable); Response response = null; try { response = call.execute(); if (response.isSuccessful()) { observer.onNext((T) response.body()); } else { Throwable t = new HttpException(response); try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } catch (Throwable t) { Exceptions.throwIfFatal(t); if (!disposable.isDisposed()) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } observer.onComplete(); } } private static final class CallDisposable implements Disposable { private volatile boolean disposed; private WeakReference weakCall; CallDisposable(Call call) { weakCall = new WeakReference<>(call); } @Override public void dispose() { disposed = true; if (weakCall != null) { weakCall.get().cancel(); } } @Override public boolean isDisposed() { return disposed; } } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/converter/Rxjava2CallAdapterFactories.java ================================================ package com.yanxuwen.xretrofit.converter; import com.xretrofit.CallAdapter.CallAdapter; import com.xretrofit.utils.Utils; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Type; import io.reactivex.Observable; /** * @author bsnl_yanxuwen * @date 2021/2/4 15:46 * Description : * rxjava2 适配器 */ public class Rxjava2CallAdapterFactories extends CallAdapter.Factory { public static Rxjava2CallAdapterFactories create() { return new Rxjava2CallAdapterFactories(); } @Nullable @Override public CallAdapter get(Type returnType) { Class rawType = getRawType(returnType); final Type responseType = Utils.getCallResponseType(returnType); if (rawType == Observable.class) { return new Rxjava2CallAdapter(responseType); } return null; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/http/HttpRequest.java ================================================ package com.yanxuwen.xretrofit.http; import com.xretrofit.HttpManager; public class HttpRequest { private static NetService netService; public static NetService getNetService() { try { if (netService == null) { synchronized (HttpRequest.class) { if (netService == null) { netService = (NetService) Class.forName(HttpManager.getImplName(NetService.class)) .getConstructor().newInstance(); } } } } catch (Exception e) { e.printStackTrace(); } return netService; } } ================================================ FILE: XRetrofit/app/src/main/java/com/yanxuwen/xretrofit/http/NetService.java ================================================ package com.yanxuwen.xretrofit.http; import com.xretrofit.call.Call; import com.xretrofit.call.ProgressCall; import com.yanxuwen.xretrofit_annotations.annotation.method.DELETE; import com.yanxuwen.xretrofit_annotations.annotation.method.DOWNLOAD; import com.yanxuwen.xretrofit_annotations.annotation.method.FORM; import com.yanxuwen.xretrofit_annotations.annotation.method.GET; import com.yanxuwen.xretrofit_annotations.annotation.method.POST; import com.yanxuwen.xretrofit_annotations.annotation.method.PUT; import com.yanxuwen.xretrofit_annotations.annotation.method.UPLOAD; import com.yanxuwen.xretrofit_annotations.annotation.param.Body; import com.yanxuwen.xretrofit_annotations.annotation.param.FilePath; import com.yanxuwen.xretrofit_annotations.annotation.param.Header; import com.yanxuwen.xretrofit_annotations.annotation.param.Param; import com.yanxuwen.xretrofit_annotations.annotation.param.Path; import com.yanxuwen.xretrofit_annotations.annotation.param.Query; import com.yanxuwen.xretrofit_annotations.annotation.service.NetServiceClass; import com.yanxuwen.xretrofit.bean.HomeInfoV5; import com.yanxuwen.xretrofit.bean.LoginBuild; import io.reactivex.Observable; @NetServiceClass public interface NetService { /** * get */ @GET("api/manage-home/v5/home/detail-v2") Observable get(@Query("page") int page, @Query("limit") int limit); /** * get请求(URL中带有参数) */ @GET("api/manage-home/v5/home/{version}") Call get(@Path("version") String version, @Query("page") int page, @Query("limit") int limit); /** * 表单提交 */ @FORM @POST("https://bx-uat.bisinuolan.cn/api/login/mobile") Call postForm(@Param("mobile") String mobile, @Param("sms_code") String sms_code); /** * json提交 */ @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") Call postJson(@Param("userId") String userId); /** * json 整串提交 */ @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") Call postJson2(@Body String json); /** * json 实体类提交 */ @POST("https://bx-co-uat-appgateway.bsnlco.com/api/customer/v1/open/user/level/my") Call postJson(@Body LoginBuild json); /** * put 提交 */ @PUT("http://api.sdwhcn.com:5056/v1/member") Call put(@Header("Authorization") String header, @Query("nickname") String nickname, @Query("signature") String signature, @Query("area") String area); /** * delete 提交 */ @DELETE("http://api.sdwhcn.com:5056/v1/member_collect_article/{id}") Call delete(@Header("Authorization") String header, @Path("id") String id); /** * */ @DOWNLOAD("https://ztjyupdate.ztjy61.com/333897c77ec9a86605006679c7a4b418-ZTJY") ProgressCall download(@FilePath String file); /** * 多图上传 */ @UPLOAD("https://bxuatapi.bisinuolan.cn/api/bsnl-oss/appUploadShot") ProgressCall upload(@FilePath String file, @Param("shot") boolean shot); } ================================================ FILE: XRetrofit/app/src/main/res/drawable/ic_launcher_background.xml ================================================ ================================================ FILE: XRetrofit/app/src/main/res/drawable-v24/ic_launcher_foreground.xml ================================================ ================================================ FILE: XRetrofit/app/src/main/res/layout/activity_main.xml ================================================