diff --git a/EasyHttp.apk b/EasyHttp.apk index 2ea264c..2fdb6d1 100644 Binary files a/EasyHttp.apk and b/EasyHttp.apk differ diff --git a/HelpDoc.md b/HelpDoc.md index a7acaf7..f234cd3 100644 --- a/HelpDoc.md +++ b/HelpDoc.md @@ -1,7 +1,5 @@ # 目录 -> 文档大致分为三类 - * [集成文档](#集成文档) * [使用文档](#使用文档) @@ -23,10 +21,10 @@ #### 关于 Http 明文请求 -> Android P 限制了明文流量的网络请求,非加密的流量请求都会被系统禁止掉。 +* Android P 限制了明文流量的网络请求,非加密的流量请求都会被系统禁止掉。 如果当前应用的请求是 http 请求,而非 https ,这样就会导系统禁止当前应用进行该请求,如果 WebView 的 url 用 http 协议,同样会出现加载失败,https 不受影响 -> 在 res 下新建一个 xml 目录,然后创建一个名为:network_security_config.xml 文件 ,该文件内容如下 +* 在 res 下新建一个 xml 目录,然后创建一个名为:network_security_config.xml 文件 ,该文件内容如下 ```xml @@ -35,7 +33,7 @@ ``` -> 然后在 AndroidManifest.xml application 标签内应用上面的xml配置 +* 然后在 AndroidManifest.xml application 标签内应用上面的xml配置 ```xml 需要配置请求结果处理,具体封装可以参考 [RequestHandler](app/src/main/java/com/hjq/http/demo/http/model/RequestHandler.java) +* 需要配置请求结果处理,具体封装可以参考 [RequestHandler](app/src/main/java/com/hjq/http/demo/http/model/RequestHandler.java) ```java OkHttpClient okHttpClient = new OkHttpClient.Builder() @@ -90,13 +88,30 @@ EasyConfig.with(okHttpClient) .into(); ``` -> 上述是创建配置,更新配置可以使用 +* 上述是创建配置,更新配置可以使用 ```java EasyConfig.getInstance() .addParam("token", data.getData().getToken()); ``` +#### 混淆规则 + +```groovy +# OkHttp3 +-keepattributes Signature +-keepattributes *Annotation* +-keep class okhttp3.** { *; } +-keep interface okhttp3.** { *; } +-dontwarn okhttp3.** +-dontwarn okio.** + +# 不混淆这个包下的字段名 +-keepclassmembernames class com.hjq.http.demo.http.** { + ; +} +``` + # 使用文档 #### 配置接口 @@ -142,10 +157,18 @@ public final class LoginApi implements IRequestApi { * implements IRequestPath:实现这个接口之后可以重新指定这个请求的接口路径 * implements IRequestType:实现这个接口之后可以重新指定这个请求的提交方式 + +* 字段作为请求参数的衡量标准 + + * 假设某个字段的属性值为空,那么这个字段将不会作为请求参数发送给后台 + + * 假设果某个字段类型是 String,属性值是空字符串,那么这个字段就会作为请求参数,如果是空对象则不会 + + * 假设某个字段类型是 int,因为基本数据类型没有空值,所以这个字段一定会作为请求参数,但是可以换成 Integer 对象来避免,因为 Integer 的默认值是 null #### 发起请求 -> 需要配置请求状态及生命周期处理,具体封装可以参考 [BaseActivity](app/src/main/java/com/hjq/http/demo/BaseActivity.java) +* 需要配置请求状态及生命周期处理,具体封装可以参考 [BaseActivity](app/src/main/java/com/hjq/http/demo/BaseActivity.java) ```java EasyHttp.post(this) @@ -161,8 +184,38 @@ EasyHttp.post(this) }); ``` +* 这里展示 post 用法,另外 EasyHttp 还支持 get、head、delete、put、patch 请求方式,这里不再过多演示 + #### 上传文件 +```java +public final class UpdateImageApi implements IRequestApi, IRequestType { + + @Override + public String getApi() { + return "upload/"; + } + + @Override + public BodyType getType() { + // 上传文件需要使用表单的形式提交 + return BodyType.FORM; + } + + /** 本地图片 */ + private File image; + + public UpdateImageApi(File image) { + this.image = image; + } + + public UpdateImageApi setImage(File image) { + this.image = image; + return this; + } +} +``` + ```java EasyHttp.post(this) .api(new UpdateImageApi(file)) @@ -174,7 +227,7 @@ EasyHttp.post(this) } @Override - public void onUpdate(long totalByte, long updateByte, int progress) { + public void onProgress(int progress) { mProgressBar.setProgress(progress); } @@ -197,7 +250,7 @@ EasyHttp.post(this) #### 下载文件 -> 下载缓存策略:在指定下载文件 md5 或者后台有返回 md5 的情况下,下载框架默认开启下载缓存模式,如果这个文件已经存在手机中,并且经过 md5 校验文件完整,框架就不会重复下载,而是直接回调下载监听。减轻服务器压力,减少用户等待时间。 +* 下载缓存策略:在指定下载文件 md5 或者后台有返回 md5 的情况下,下载框架默认开启下载缓存模式,如果这个文件已经存在手机中,并且经过 md5 校验文件完整,框架就不会重复下载,而是直接回调下载监听。减轻服务器压力,减少用户等待时间。 ```java EasyHttp.download(this) @@ -214,7 +267,7 @@ EasyHttp.download(this) } @Override - public void onProgress(File file, long totalByte, long downloadByte, int progress) { + public void onProgress(File file, int progress) { mProgressBar.setProgress(progress); } @@ -244,7 +297,7 @@ try { HttpData data = EasyHttp.post(MainActivity.this) .api(new SearchBlogsApi() .setKeyword("搬砖不再有")) - .execute(new DataClass>() {}); + .execute(new ResponseClass>() {}); ToastUtils.show("请求成功,请看日志"); } catch (Exception e) { e.printStackTrace(); @@ -582,7 +635,7 @@ EasyConfig.getInstance().setLogEnabled(false); #### 框架指定只能传入 LifecycleOwner,我想传入其他对象怎么办? -* 其中 AppCompatActivity 和 AndroidX.Fragment 都是 LifecycleOwner 子类的,这个是毋庸置疑的 +* 其中 AndroidX.AppCompatActivity 和 AndroidX.Fragment 都是 LifecycleOwner 子类的,这个是毋庸置疑的 * 但是你如果传入的是 Activity 对象,并非 AppCompatActivity 对象,那么你可以这样写 @@ -628,4 +681,34 @@ EasyHttp.cancel(LifecycleOwner lifecycleOwner); EasyHttp.cancel(Object tag); // 取消所有请求 EasyHttp.cancel(); -``` \ No newline at end of file +``` + +#### getHost、getPath、getApi 方法之间的作用和区别? + +* Host:服务器主机的地址 + +* Path:除主机地址之外的路径 + +* Api:业务模块地址 + +* 我举个栗子:[https://www.baidu.com/api/user/getInfo](https://www.baidu.com/),那么标准的写法就是 + +```java +public final class XxxApi implements IRequestServer, IRequestApi { + + @Override + public String getHost() { + return "https://www.baidu.com/"; + } + + @Override + public String getPath() { + return "api/"; + } + + @Override + public String getApi() { + return "user/getInfo"; + } +} +``` diff --git a/README.md b/README.md index 68a5348..64ac6f6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 网络请求框架 +# 简单易用的网络框架 > 码云地址:[Gitee](https://gitee.com/getActivity/EasyHttp) @@ -6,6 +6,20 @@ ![](EasyHttp.jpg) +> 另外对 OkHttp 源码感兴趣的同学可以看下面几篇文章 + +* [OkHttp 精讲:拦截器执行原理](https://www.jianshu.com/p/e0f324fd9411) + +* [OkHttp 精讲:RetryAndFollowUpInterceptor](https://www.jianshu.com/p/40636d32cb67) + +* [OkHttp 精讲:BridgeInterceptor](https://www.jianshu.com/p/fab2d74de900) + +* [OkHttp 精讲:CacheInterceptor](https://www.jianshu.com/p/44fad764c0ae) + +* [OkHttp 精讲:ConnectInterceptor](https://www.jianshu.com/p/a3a774fdff4f) + +* [OkHttp 精讲:CallServerInterceptor](https://www.jianshu.com/p/aa77af6251ff) + #### Gradle 集成 ```groovy @@ -18,61 +32,57 @@ android { } dependencies { - implementation 'com.hjq:http:8.6' + // 网络请求框架:https://github.com/getActivity/EasyHttp + implementation 'com.hjq:http:8.8' + // OkHttp 框架:https://github.com/square/okhttp + // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.12' - implementation 'com.google.code.gson:gson:2.8.5' } ``` -#### 具体用法[请点击这里查看](HelpDoc.md) +## [框架的具体用法请点击这里查看](HelpDoc.md) #### 不同网络请求框架之间的对比 | 功能 | [EasyHttp](https://github.com/getActivity/EasyHttp) | [Retrofit](https://github.com/square/retrofit) | [OkGo](https://github.com/jeasonlzy/okhttp-OkGo) | | :----: | :------: | :-----: | :-----: | +| 对应版本 | 8.8 | 2.9.0 | 3.0.4 | | 动态 Host | 支持 | 不支持 | 支持 | | 全局参数 | 支持 | 不支持 | 支持 | | 超时重试 | 支持 | 不支持 | 支持 | -| 极速下载 | 支持 | 不支持 | 不支持 | | 下载校验 | 支持 | 不支持 | 不支持 | +| 极速下载 | 支持 | 不支持 | 不支持 | | 注解数量 | 3 个 | 25 个 | 0 个 | -| 上传文件类型 | File / InputStream | RequestBody | File | +| 上传文件类型 | File / InputStream / RequestBody | RequestBody | File | | 批量上传文件 | 支持 | 不支持 | 支持 | | 上传进度监听 | 支持 | 不支持 | 支持 | -| Json 参数提交 | 支持 | 支持 | 支持 | +| Json 参数提交 | 支持 | 不支持 | 支持 | | 请求生命周期 | 自动管控 | 需要封装 | 需要封装 | -| 参数传值方式 | 字段名 + 字段值 | 方法参数名 + 方法参数值 | 定义 key 和 value | +| 参数传值方式 | 字段名 + 字段值 | 方法参数名 + 方法参数值 | 定义 Key + Value | | 参数灵活性 | 不强制传入 | 强制全部传入 | 不强制传入 | +| 自定义 RequestBody | 支持 | 支持 | 支持 | +| minSdk 要求 | API 14+ | API 21+ | API 14+ | +| class 文件数量 | 70 个 | 54 个 | 85 个 | +| aar 包大小 | [55 KB](https://bintray.com/getactivity/maven/http#files/com/hjq/http) | [123 KB](https://bintray.com/bintray/jcenter/com.squareup.retrofit2%3Aretrofit#files) | [131 KB](https://bintray.com/jeasonlzy/maven/okgo#files/com/lzy/net/okgo) | | 框架维护状态 | 维护中 | 维护中 | 停止维护 | -* Retrofit 在我看来并不是那么好用,因为很多常用的功能实现起来比较麻烦,动态 Host 要写拦截器,日志打印要写拦截器,就连最常用的添加全局参数也要写拦截器,一个拦截器意味着要写很多代码,如果写得不够严谨还有可能出现 Bug,从而影响整个 OkHttp 请求流程,我经常在想这些功能能不能都用一句代码搞定,因为我觉得这些功能是框架设计的时候应该考虑的,这便是我做这个框架的初心。 +* Retrofit 在我看来并不是那么好用,因为很多常用的功能实现起来比较麻烦,动态 Host 要写拦截器,日志打印要写拦截器,就连最常用的添加全局参数也要写拦截器,一个拦截器意味着要写很多代码,如果写得不够严谨还有可能出现 Bug,从而影响整个 OkHttp 请求流程,我经常在想这些功能能不能都用一句代码搞定,因为我觉得这些功能是设计框架的时候本应该考虑的,这便是我做这个框架的初心。 -* 本框架采用了 OOP 思想,一个请求代表一个对象,通过类的继承和实现的特性来实现接口的动态化,几乎涵盖接口开发中所有的功能,使用起来非常简单灵活。 +* 本框架采用了 OOP 思想,一个请求代表一个对象,通过类的继承和实现的特性来实现接口的动态化配置,几乎涵盖接口开发中所有的功能,使用起来非常简单灵活。 * 有很多人觉得写一个接口类很麻烦,这个点确实有点麻烦,但是这块的付出是有收获的,从前期开发的效率考虑:OkGo > EasyHttp > Retrofit,但是从后期维护的效率考虑:EasyHttp > Retrofit > OkGo,之所以比较这三个框架,是因为框架的设计思想不同,但是我始终认为 EasyHttp 才是最好的设计,所以我创造了它。 -* 前期开发和后期维护哪个更重要?我觉得都重要,但是如果两者之间有利益冲突,我会毫不犹豫选择后期维护,因为前期开发占据的是小头,后期的持续维护才是大头。 +* 前期开发和后期维护哪个更重要?我觉得都重要,但是如果两者之间存在利益冲突,我会毫不犹豫地选择后期维护,因为前期开发占据的是小头,后期的持续维护才是大头。 -#### 混淆规则 +#### 极速下载功能介绍 -```groovy -# OkHttp3 --keepattributes Signature --keepattributes *Annotation* --keep class okhttp3.** { *; } --keep interface okhttp3.** { *; } --dontwarn okhttp3.** --dontwarn okio.** - -# 不混淆这个包下的字段名 --keepclassmembernames class com.hjq.http.demo.http.** { - ; -} -``` +* 其实本质上面和极速秒传的原理是差不多的,只不过一个是上传,一个是下载。而极速上传是将本地文件的 MD5 值和服务器上面的进行比对,如果服务器存在这个 MD5 值的文件,就将这份文件映射一份到这个用户的网盘上面,从而达到了极速秒传的效果。而极速下载也是同理,根据后台给的文件 MD5 值和本地文件进行对比,如果存在这个文件并且 MD5 值一致,证明这个文件和服务器上面的文件是一致的,那么就直接跳过下载,直接回调下载成功监听。 + +* 极速秒传和极速下载两者相同的共同点就是,利用缓存来达到极速的效果,只不过一者通过的是服务器的缓存,另一者使用的是本地的缓存,这两者都有一个共同的特点,就是减少服务器的压力,节省用户的等待时间。 #### 作者的其他开源项目 -* 安卓架构:[AndroidProject](https://github.com/getActivity/AndroidProject) +* 安卓技术中台:[AndroidProject](https://github.com/getActivity/AndroidProject) * 日志框架:[Logcat](https://github.com/getActivity/Logcat) diff --git a/app/build.gradle b/app/build.gradle index c1058c2..9c0a16c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,12 +14,12 @@ android { } defaultConfig { - applicationId "com.hjq.http.demo" - minSdkVersion 14 + applicationId 'com.hjq.http.demo' + minSdkVersion 16 targetSdkVersion 30 - versionCode 86 - versionName "8.6" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + versionCode 88 + versionName '8.8' + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -49,16 +49,17 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.0-alpha02' // 标题栏:https://github.com/getActivity/TitleBar - implementation 'com.hjq:titlebar:8.0' + implementation 'com.hjq:titlebar:8.2' // 吐司工具类:https://github.com/getActivity/ToastUtils implementation 'com.hjq:toast:8.8' // 权限请求框架:https://github.com/getActivity/XXPermissions - implementation 'com.hjq:xxpermissions:8.8' + implementation 'com.hjq:xxpermissions:9.2' // Json 解析框架:https://github.com/google/gson implementation 'com.google.code.gson:gson:2.8.5' // OkHttp 框架:https://github.com/square/okhttp // 升级注意事项:https://www.jianshu.com/p/d12d0f536f55 + // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.12' // 日志调试:https://github.com/getActivity/Logcat - debugImplementation 'com.hjq:logcat:8.6' + debugImplementation 'com.hjq:logcat:9.0' } \ No newline at end of file diff --git a/app/src/main/java/com/hjq/http/demo/MainActivity.java b/app/src/main/java/com/hjq/http/demo/MainActivity.java index 2f748b4..bd1af6d 100644 --- a/app/src/main/java/com/hjq/http/demo/MainActivity.java +++ b/app/src/main/java/com/hjq/http/demo/MainActivity.java @@ -24,8 +24,8 @@ import com.hjq.http.listener.HttpCallback; import com.hjq.http.listener.OnDownloadListener; import com.hjq.http.listener.OnUpdateListener; -import com.hjq.http.model.DataClass; import com.hjq.http.model.HttpMethod; +import com.hjq.http.model.ResponseClass; import com.hjq.permissions.OnPermission; import com.hjq.permissions.Permission; import com.hjq.permissions.XXPermissions; @@ -134,7 +134,7 @@ public void onSucceed(HttpData result) { HttpData data = EasyHttp.post(MainActivity.this) .api(new SearchBlogsApi() .setKeyword("搬砖不再有")) - .execute(new DataClass>() {}); + .execute(new ResponseClass>() {}); ToastUtils.show("同步请求成功,请看日志"); } catch (Exception e) { e.printStackTrace(); @@ -163,12 +163,11 @@ public void onStart(Call call) { } @Override - public void onUpdate(long totalByte, long updateByte, int progress) { + public void onProgress(int progress) { mProgressBar.setProgress(progress); } @Override - public void onSucceed(Void result) { ToastUtils.show("上传成功"); } @@ -203,7 +202,7 @@ public void onStart(File file) { } @Override - public void onProgress(File file, long totalByte, long downloadByte, int progress) { + public void onProgress(File file, int progress) { mProgressBar.setProgress(progress); } diff --git a/app/src/main/java/com/hjq/http/demo/http/request/UpdateImageApi.java b/app/src/main/java/com/hjq/http/demo/http/request/UpdateImageApi.java index 2e09357..ef3f259 100644 --- a/app/src/main/java/com/hjq/http/demo/http/request/UpdateImageApi.java +++ b/app/src/main/java/com/hjq/http/demo/http/request/UpdateImageApi.java @@ -4,8 +4,6 @@ import com.hjq.http.config.IRequestServer; import java.io.File; -import java.util.ArrayList; -import java.util.List; /** * author : Android 轮子哥 @@ -28,15 +26,12 @@ public String getApi() { /** 本地图片 */ private File image; - private List files = new ArrayList<>(); - public UpdateImageApi(File image) { this.image = image; } public UpdateImageApi setImage(File image) { this.image = image; - files.add(image); return this; } } \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index ff7bc2d..4c11e88 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -12,14 +12,17 @@ android { defaultConfig { minSdkVersion 14 - versionCode 86 - versionName "8.6" + versionCode 88 + versionName "8.8" } } dependencies { + // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.12' + // noinspection GradleDependency implementation 'androidx.lifecycle:lifecycle-common:2.1.0' + // noinspection GradleDependency implementation 'androidx.lifecycle:lifecycle-runtime:2.1.0' } @@ -27,7 +30,7 @@ publish { userOrg = 'getactivity' groupId = 'com.hjq' artifactId = 'http' - version = '8.6' + version = '8.8' description = 'Easy-to-use network request framework' website = "https://github.com/getActivity/EasyHttp" } diff --git a/library/src/main/java/com/hjq/http/EasyConfig.java b/library/src/main/java/com/hjq/http/EasyConfig.java index ee6ed41..979e85b 100644 --- a/library/src/main/java/com/hjq/http/EasyConfig.java +++ b/library/src/main/java/com/hjq/http/EasyConfig.java @@ -45,7 +45,7 @@ public static EasyConfig with(OkHttpClient client) { private IRequestHandler mHandler; /** 请求拦截器 */ private IRequestInterceptor mInterceptor; - /** 日志打印策略 */ + /** 日志打印策略 */ private ILogStrategy mLogStrategy; /** OkHttp 客户端 */ diff --git a/library/src/main/java/com/hjq/http/EasyHttp.java b/library/src/main/java/com/hjq/http/EasyHttp.java index 3c370d0..079dba9 100644 --- a/library/src/main/java/com/hjq/http/EasyHttp.java +++ b/library/src/main/java/com/hjq/http/EasyHttp.java @@ -30,7 +30,7 @@ public final class EasyHttp { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static GetRequest get(LifecycleOwner lifecycleOwner) { - return new GetRequest(lifecycleOwner).tag(lifecycleOwner); + return new GetRequest(lifecycleOwner); } /** @@ -42,7 +42,7 @@ public static GetRequest get(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static PostRequest post(LifecycleOwner lifecycleOwner) { - return new PostRequest(lifecycleOwner).tag(lifecycleOwner); + return new PostRequest(lifecycleOwner); } /** @@ -54,7 +54,7 @@ public static PostRequest post(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static HeadRequest head(LifecycleOwner lifecycleOwner) { - return new HeadRequest(lifecycleOwner).tag(lifecycleOwner); + return new HeadRequest(lifecycleOwner); } /** @@ -66,7 +66,7 @@ public static HeadRequest head(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static DeleteRequest delete(LifecycleOwner lifecycleOwner) { - return new DeleteRequest(lifecycleOwner).tag(lifecycleOwner); + return new DeleteRequest(lifecycleOwner); } /** @@ -78,7 +78,7 @@ public static DeleteRequest delete(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static PutRequest put(LifecycleOwner lifecycleOwner) { - return new PutRequest(lifecycleOwner).tag(lifecycleOwner); + return new PutRequest(lifecycleOwner); } /** @@ -90,7 +90,7 @@ public static PutRequest put(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static PatchRequest patch(LifecycleOwner lifecycleOwner) { - return new PatchRequest(lifecycleOwner).tag(lifecycleOwner); + return new PatchRequest(lifecycleOwner); } /** @@ -102,14 +102,14 @@ public static PatchRequest patch(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ public static DownloadRequest download(LifecycleOwner lifecycleOwner) { - return new DownloadRequest(lifecycleOwner).tag(lifecycleOwner); + return new DownloadRequest(lifecycleOwner); } /** * 取消请求 */ public static void cancel(LifecycleOwner lifecycleOwner) { - cancel(lifecycleOwner.toString()); + cancel(String.valueOf(lifecycleOwner)); } /** diff --git a/library/src/main/java/com/hjq/http/EasyUtils.java b/library/src/main/java/com/hjq/http/EasyUtils.java index 028e504..8e68838 100644 --- a/library/src/main/java/com/hjq/http/EasyUtils.java +++ b/library/src/main/java/com/hjq/http/EasyUtils.java @@ -6,6 +6,7 @@ import com.hjq.http.annotation.HttpIgnore; import com.hjq.http.annotation.HttpRename; +import com.hjq.http.body.UpdateBody; import org.json.JSONArray; import org.json.JSONException; @@ -14,6 +15,7 @@ import java.io.Closeable; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; @@ -28,6 +30,7 @@ import java.util.Map; import java.util.Set; +import okhttp3.MultipartBody; import okhttp3.RequestBody; /** @@ -129,26 +132,42 @@ public static boolean isBeanType(Object object) { } /** - * 判断字段数组是否有存在流参数 + * 判断是否包含存在流参数 */ public static boolean isMultipart(Field[] fields) { for (Field field : fields) { // 允许访问私有字段 field.setAccessible(true); + // 获取对象的类型 Class clazz = field.getType(); - if (File.class.equals(clazz)) { - return true; - } else if (InputStream.class.equals(clazz)) { - return true; - } else if (RequestBody.class.equals(clazz)) { - return true; - } else if (List.class.equals(clazz)) { - Type[] actualTypeArguments = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); - if (actualTypeArguments.length == 1 && File.class.equals(actualTypeArguments[0])) { - return true; + + // 获取对象上面实现的接口 + Class[] interfaces = clazz.getInterfaces(); + for (int i = 0; i <= interfaces.length; i++) { + Class temp; + if (i == interfaces.length) { + temp = clazz; + } else { + temp = interfaces[i]; + } + + // 判断类型是否是 List + if (List.class.equals(temp)) { + Type[] actualTypeArguments = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); + if (actualTypeArguments.length == 1 && File.class.equals(actualTypeArguments[0])) { + return true; + } } } + + do { + if (File.class.equals(clazz) || InputStream.class.equals(clazz) || RequestBody.class.equals(clazz)) { + return true; + } + // 获取对象的父类类型 + clazz = clazz.getSuperclass(); + } while (clazz != null && !Object.class.equals(clazz)); } return false; } @@ -243,12 +262,6 @@ public static HashMap beanToHashMap(Object object) { for (Field field : fields) { // 允许访问私有字段 field.setAccessible(true); - // 如果是内部类则会出现一个字段名为 this$0 的外部类对象,会导致无限递归,这里要忽略掉 - // 如果使用静态内部类则不会出现这个问题 - if (object.getClass().toString().startsWith(field.getType().toString())) { - //"class com.hjq.http.demo.http.request.SearchBlogsApi$TestBean".startsWith("class com.hjq.http.demo.http.request.SearchBlogsApi") - continue; - } try { @@ -256,8 +269,8 @@ public static HashMap beanToHashMap(Object object) { Object value = field.get(object); // 前提是这个字段值不能为空(基本数据类型有默认的值,而对象默认的值为 null) - if (isEmpty(value)) { - // 遍历下一个字段 + // 又或者这个字段需要忽略,则进行忽略 + if (isEmpty(value) || field.isAnnotationPresent(HttpIgnore.class)) { continue; } @@ -267,12 +280,11 @@ public static HashMap beanToHashMap(Object object) { key = field.getAnnotation(HttpRename.class).value(); } else { key = field.getName(); - } - - // 如果这个字段需要忽略,则进行忽略 - if (field.isAnnotationPresent(HttpIgnore.class)) { - // 遍历下一个字段 - continue; + // 如果是内部类则会出现一个字段名为 this$0 的外部类对象,会导致无限递归,这里要忽略掉,如果使用静态内部类则不会出现这个问题 + // 和规避 Kotlin 自动生成的伴生对象:https://github.com/getActivity/EasyHttp/issues/15 + if (key.matches("this\\$\\d+") || "Companion".equals(key)) { + continue; + } } if (data == null) { @@ -316,7 +328,7 @@ public static Type getReflectType(Object object) { /** * 获取进度百分比 */ - public static int getProgressPercent(long totalByte, long currentByte) { + public static int getProgressProgress(long totalByte, long currentByte) { // 计算百分比,这里踩了两个坑 // 当文件很大的时候:字节数 * 100 会超过 int 最大值,计算结果会变成负数 // 还有需要注意的是,long 除以 long 等于 long,这里的字节数除以总字节数应该要 double 类型的 @@ -332,4 +344,33 @@ public static String encodeString(String text) { } return URLEncoder.encode(text); } + + /** + * 根据 File 对象创建一个流媒体 + */ + public static MultipartBody.Part createPart(String key, File file) { + if (file.exists() && file.isFile()) { + try { + // 文件名必须不能带中文,所以这里要编码 + return MultipartBody.Part.createFormData(key, EasyUtils.encodeString(file.getName()), new UpdateBody(file)); + } catch (FileNotFoundException e) { + EasyLog.print(e); + } + } else { + EasyLog.print("文件不存在,将被忽略上传:" + key + " = " + file.getPath()); + } + return null; + } + + /** + * 根据 InputStream 对象创建一个流媒体 + */ + public static MultipartBody.Part createPart(String key, InputStream inputStream) { + try { + return MultipartBody.Part.createFormData(key, null, new UpdateBody(inputStream, key)); + } catch (IOException e) { + EasyLog.print(e); + } + return null; + } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/JsonArrayBody.java b/library/src/main/java/com/hjq/http/body/JsonArrayBody.java deleted file mode 100644 index ee4f8cc..0000000 --- a/library/src/main/java/com/hjq/http/body/JsonArrayBody.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hjq.http.body; - -import org.json.JSONArray; - -import java.io.IOException; -import java.util.List; - -import okio.BufferedSink; - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/EasyHttp - * time : 2019/12/28 - * desc : JsonArray 参数提交 - */ -public final class JsonArrayBody extends JsonBaseBody { - - private final JSONArray mJsonArray; - - public JsonArrayBody() { - this(new JSONArray()); - } - - public JsonArrayBody(List list) { - this(new JSONArray(list)); - } - - public JsonArrayBody(JSONArray jsonArray) { - mJsonArray = jsonArray; - } - - public JSONArray getJsonObject() { - return mJsonArray; - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - writeTo(sink, mJsonArray.toString()); - } -} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/JsonBaseBody.java b/library/src/main/java/com/hjq/http/body/JsonBaseBody.java deleted file mode 100644 index 68d6304..0000000 --- a/library/src/main/java/com/hjq/http/body/JsonBaseBody.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.hjq.http.body; - -import java.io.IOException; - -import okhttp3.MediaType; -import okhttp3.RequestBody; -import okio.BufferedSink; - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/EasyHttp - * time : 2019/12/28 - * desc : Json 参数提交 - */ -public abstract class JsonBaseBody extends RequestBody { - - private static final MediaType CONTENT_TYPE = MediaType.get("application/json; charset=utf-8"); - - @Override - public MediaType contentType() { - return CONTENT_TYPE; - } - - public void writeTo(BufferedSink sink, String json) throws IOException { - byte[] bytes = json.getBytes(); - sink.write(bytes, 0, bytes.length); - } -} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/JsonBody.java b/library/src/main/java/com/hjq/http/body/JsonBody.java new file mode 100644 index 0000000..192b648 --- /dev/null +++ b/library/src/main/java/com/hjq/http/body/JsonBody.java @@ -0,0 +1,64 @@ +package com.hjq.http.body; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.BufferedSink; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/EasyHttp + * time : 2019/12/28 + * desc : Json 参数提交 + */ +public final class JsonBody extends RequestBody { + + /** Json 文本数据 */ + private final String mJson; + + public JsonBody(Map map) { + this(new JSONObject(map)); + } + + public JsonBody(JSONObject jsonObject) { + mJson = jsonObject.toString(); + } + + public JsonBody(List list) { + this(new JSONArray(list)); + } + + public JsonBody(JSONArray jsonArray) { + mJson = jsonArray.toString(); + } + + @Override + public MediaType contentType() { + return MediaType.get("application/json; charset=utf-8"); + } + + @Override + public long contentLength() { + return mJson.length(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + byte[] bytes = mJson.getBytes(); + sink.write(bytes, 0, bytes.length); + } + + @NonNull + @Override + public String toString() { + return mJson; + } +} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/JsonObjectBody.java b/library/src/main/java/com/hjq/http/body/JsonObjectBody.java deleted file mode 100644 index 57acca5..0000000 --- a/library/src/main/java/com/hjq/http/body/JsonObjectBody.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hjq.http.body; - -import org.json.JSONObject; - -import java.io.IOException; -import java.util.Map; - -import okio.BufferedSink; - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/EasyHttp - * time : 2019/12/28 - * desc : JsonObject 参数提交 - */ -public final class JsonObjectBody extends JsonBaseBody { - - private final JSONObject mJsonObject; - - public JsonObjectBody() { - this(new JSONObject()); - } - - public JsonObjectBody(Map map) { - this(new JSONObject(map)); - } - - public JsonObjectBody(JSONObject jsonObject) { - mJsonObject = jsonObject; - } - - public JSONObject getJsonObject() { - return mJsonObject; - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - writeTo(sink, mJsonObject.toString()); - } -} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/MultipartBodyProxy.java b/library/src/main/java/com/hjq/http/body/MultipartBodyProxy.java deleted file mode 100644 index 3508253..0000000 --- a/library/src/main/java/com/hjq/http/body/MultipartBodyProxy.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.hjq.http.body; - -import androidx.annotation.Nullable; -import androidx.lifecycle.LifecycleOwner; - -import com.hjq.http.EasyLog; -import com.hjq.http.EasyUtils; -import com.hjq.http.lifecycle.HttpLifecycleControl; -import com.hjq.http.listener.OnUpdateListener; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import okhttp3.MediaType; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import okio.Buffer; -import okio.BufferedSink; -import okio.ForwardingSink; -import okio.Okio; - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/EasyHttp - * time : 2020/08/15 - * desc : MultipartBody 代理类 - */ -public final class MultipartBodyProxy extends RequestBody { - - private final MultipartBody mMultipartBody; - private final OnUpdateListener mListener; - private final LifecycleOwner mLifecycleOwner; - - public MultipartBodyProxy(MultipartBody body, LifecycleOwner lifecycleOwner, OnUpdateListener listener) { - mMultipartBody = body; - mLifecycleOwner = lifecycleOwner; - mListener = listener; - } - - @Override - public MediaType contentType() { - return mMultipartBody.contentType(); - } - - @Override - public long contentLength() throws IOException { - return mMultipartBody.contentLength(); - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - final long totalByte = contentLength(); - mMultipartBody.writeTo(sink = Okio.buffer(new ForwardingSink(sink) { - - private long updateByte; - - @Override - public void write(Buffer source, long byteCount) throws IOException { - super.write(source, byteCount); - updateByte += byteCount; - int progress = EasyUtils.getProgressPercent(totalByte, updateByte); - EasyLog.print("正在进行上传" + - ",总字节:" + totalByte + - ",已上传:" + updateByte + - ",进度:" + progress + "%"); - EasyUtils.post(() -> { - if (mListener != null && HttpLifecycleControl.isLifecycleActive(mLifecycleOwner)) { - mListener.onUpdate(totalByte, updateByte, progress); - } - }); - } - })); - sink.flush(); - } - - public static final class Builder { - - private final MultipartBody.Builder mBuilder; - private OnUpdateListener mListener; - private LifecycleOwner mLifecycleOwner; - - public Builder() { - mBuilder = new MultipartBody.Builder(); - } - - public Builder setType(MediaType type) { - mBuilder.setType(type); - return this; - } - - public Builder addPart(MultipartBody.Part part) { - mBuilder.addPart(part); - return this; - } - - public Builder addFormDataPart(String name, String value) { - mBuilder.addFormDataPart(name, value); - return this; - } - - public Builder addFormDataPart(String name, @Nullable String filename, RequestBody body) { - mBuilder.addFormDataPart(name, filename, body); - return this; - } - - public Builder setOnUpdateListener(OnUpdateListener listener) { - mListener = listener; - return this; - } - - public Builder setLifecycleOwner(LifecycleOwner lifecycleOwner) { - mLifecycleOwner = lifecycleOwner; - return this; - } - - public MultipartBodyProxy build() { - return new MultipartBodyProxy(mBuilder.build(), mLifecycleOwner, mListener); - } - } - - /** - * 根据 File 对象创建一个流媒体 - */ - public static MultipartBody.Part createPart(String key, File file) { - if (file.exists() && file.isFile()) { - try { - // 文件名必须不能带中文,所以这里要编码 - return MultipartBody.Part.createFormData(key, EasyUtils.encodeString(file.getName()), new UpdateBody(file)); - } catch (FileNotFoundException e) { - EasyLog.print(e); - } - } else { - EasyLog.print("文件不存在,将被忽略上传:" + key + " = " + file.getPath()); - } - return null; - } - - /** - * 根据 InputStream 对象创建一个流媒体 - */ - public static MultipartBody.Part createPart(String key, InputStream inputStream) { - try { - return MultipartBody.Part.createFormData(key, null, new UpdateBody(inputStream, key)); - } catch (IOException e) { - EasyLog.print(e); - } - return null; - } -} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/ProgressBody.java b/library/src/main/java/com/hjq/http/body/ProgressBody.java new file mode 100644 index 0000000..a18e0c2 --- /dev/null +++ b/library/src/main/java/com/hjq/http/body/ProgressBody.java @@ -0,0 +1,83 @@ +package com.hjq.http.body; + +import androidx.lifecycle.LifecycleOwner; + +import com.hjq.http.EasyLog; +import com.hjq.http.EasyUtils; +import com.hjq.http.lifecycle.HttpLifecycleControl; +import com.hjq.http.listener.OnUpdateListener; + +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/EasyHttp + * time : 2020/08/15 + * desc : RequestBody 代理类(用于获取上传进度) + */ +public final class ProgressBody extends RequestBody { + + private final RequestBody mRequestBody; + private final OnUpdateListener mListener; + private final LifecycleOwner mLifecycleOwner; + + /** 总字节数 */ + private long mTotalByte; + /** 已上传字节数 */ + private long mUpdateByte; + /** 上传进度值 */ + private int mUpdateProgress; + + public ProgressBody(RequestBody body, LifecycleOwner lifecycleOwner, OnUpdateListener listener) { + mRequestBody = body; + mLifecycleOwner = lifecycleOwner; + mListener = listener; + } + + @Override + public MediaType contentType() { + return mRequestBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return mRequestBody.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + mTotalByte = contentLength(); + mRequestBody.writeTo(sink = Okio.buffer(new ForwardingSink(sink) { + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + mUpdateByte += byteCount; + EasyUtils.post(() -> { + int progress = EasyUtils.getProgressProgress(mTotalByte, mUpdateByte); + if (mListener != null && HttpLifecycleControl.isLifecycleActive(mLifecycleOwner)) { + // 只有上传进度发生改变的时候才回调此方法,避免引起不必要的 View 重绘 + if (progress != mUpdateProgress) { + mUpdateProgress = progress; + mListener.onProgress(progress); + } + mListener.onByte(mTotalByte, mUpdateByte); + } + + EasyLog.print("正在进行上传" + + ",总字节:" + mTotalByte + + ",已上传:" + mUpdateByte + + ",进度:" + progress + "%"); + }); + } + })); + sink.flush(); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/StringBody.java b/library/src/main/java/com/hjq/http/body/StringBody.java new file mode 100644 index 0000000..f74476e --- /dev/null +++ b/library/src/main/java/com/hjq/http/body/StringBody.java @@ -0,0 +1,50 @@ +package com.hjq.http.body; + +import androidx.annotation.NonNull; + +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.BufferedSink; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/EasyHttp + * time : 2020/10/26 + * desc : 文本参数提交 + */ +public final class StringBody extends RequestBody { + + private final String mText; + + public StringBody() { + this(""); + } + + public StringBody(String text) { + mText = text; + } + + @Override + public MediaType contentType() { + return MediaType.get("text/plain; charset=utf-8"); + } + + @Override + public long contentLength() { + return mText.length(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + byte[] bytes = mText.getBytes(); + sink.write(bytes, 0, bytes.length); + } + + @NonNull + @Override + public String toString() { + return mText; + } +} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/UpdateBody.java b/library/src/main/java/com/hjq/http/body/UpdateBody.java index e688d25..a3d45f0 100644 --- a/library/src/main/java/com/hjq/http/body/UpdateBody.java +++ b/library/src/main/java/com/hjq/http/body/UpdateBody.java @@ -21,7 +21,7 @@ * time : 2019/12/14 * desc : 上传文件流 */ -public class UpdateBody extends RequestBody { +public final class UpdateBody extends RequestBody { public static final MediaType MEDIA_TYPE = MediaType.parse("application/octet-stream"); diff --git a/library/src/main/java/com/hjq/http/callback/DownloadCallback.java b/library/src/main/java/com/hjq/http/callback/DownloadCallback.java index 1e46749..92e074b 100644 --- a/library/src/main/java/com/hjq/http/callback/DownloadCallback.java +++ b/library/src/main/java/com/hjq/http/callback/DownloadCallback.java @@ -11,7 +11,6 @@ import com.hjq.http.lifecycle.HttpLifecycleControl; import com.hjq.http.listener.OnDownloadListener; import com.hjq.http.model.CallProxy; -import com.hjq.http.model.DownloadInfo; import java.io.File; import java.io.FileOutputStream; @@ -40,6 +39,15 @@ public final class DownloadCallback extends BaseCallback { /** 下载监听回调 */ private OnDownloadListener mListener; + /** 下载总字节 */ + private long mTotalByte; + + /** 已下载字节 */ + private long mDownloadByte; + + /** 下载进度 */ + private int mDownloadProgress; + public DownloadCallback(LifecycleOwner lifecycleOwner, CallProxy call, File file, String md5, OnDownloadListener listener) { super(lifecycleOwner, call); mFile = file; @@ -65,25 +73,24 @@ protected void onResponse(Response response) throws Exception { } } - EasyUtils.createFolder(mFile.getParentFile()); + File parentFile = mFile.getParentFile(); + if (parentFile != null) { + EasyUtils.createFolder(parentFile); + } ResponseBody body = response.body(); if (body == null) { - EasyUtils.post(() -> { - if (mListener != null && HttpLifecycleControl.isLifecycleActive(getLifecycleOwner())) { - mListener.onError(mFile, new NullBodyException("The response body is empty")); - mListener.onEnd(mFile); - } - }); - return; + throw new NullBodyException("The response body is empty"); } - DownloadInfo downloadInfo = new DownloadInfo(); - downloadInfo.setTotalByte(body.contentLength()); + mTotalByte = body.contentLength(); + if (mTotalByte < 0) { + mTotalByte = 0; + } // 如果这个文件已经下载过,并且经过校验 MD5 是同一个文件的话,就直接回调下载成功监听 - if (!TextUtils.isEmpty(mMd5) && mFile.exists() && mFile.isFile() && mMd5.equalsIgnoreCase(EasyUtils.getFileMd5(mFile))) { + if (!TextUtils.isEmpty(mMd5) && mFile.isFile() && + mMd5.equalsIgnoreCase(EasyUtils.getFileMd5(mFile))) { EasyUtils.post(() -> { if (mListener != null && HttpLifecycleControl.isLifecycleActive(getLifecycleOwner())) { - downloadInfo.setDownloadByte(downloadInfo.getTotalByte()); mListener.onComplete(mFile); mListener.onEnd(mFile); } @@ -92,29 +99,34 @@ protected void onResponse(Response response) throws Exception { } int readLength; - long downloadSize = 0; + mDownloadByte = 0; byte[] bytes = new byte[8192]; InputStream inputStream = body.byteStream(); FileOutputStream outputStream = new FileOutputStream(mFile); while ((readLength = inputStream.read(bytes)) != -1) { - downloadSize += readLength; + mDownloadByte += readLength; outputStream.write(bytes, 0, readLength); - downloadInfo.setDownloadByte(downloadSize); EasyUtils.post(() -> { if (mListener != null && HttpLifecycleControl.isLifecycleActive(getLifecycleOwner())) { - mListener.onProgress(mFile, downloadInfo.getTotalByte(), downloadInfo.getDownloadByte(), downloadInfo.getDownloadProgress()); + mListener.onByte(mFile, mTotalByte, mDownloadByte); + int progress = EasyUtils.getProgressProgress(mTotalByte, mDownloadByte); + // 只有下载进度发生改变的时候才回调此方法,避免引起不必要的 View 重绘 + if (progress != mDownloadProgress) { + mDownloadProgress = progress; + mListener.onProgress(mFile, mDownloadProgress); + } + EasyLog.print(mFile.getPath() + " 正在下载,总字节:" + mTotalByte + ",已下载:" + mDownloadByte + + ",进度:" + progress + " %"); } }); - EasyLog.print(mFile.getPath() + " 正在下载" + - ",文件总字节:" + downloadInfo.getTotalByte() + - ",已下载字节:" + downloadInfo.getDownloadByte() + - ",下载进度:" + downloadInfo.getDownloadProgress() + " %"); } - outputStream.flush(); + EasyUtils.closeStream(inputStream); + EasyUtils.closeStream(outputStream); String md5 = EasyUtils.getFileMd5(mFile); if (!TextUtils.isEmpty(mMd5) && !mMd5.equalsIgnoreCase(md5)) { - onFailure(new MD5Exception("MD5 verify failure", md5)); + // 文件 MD5 值校验失败 + throw new MD5Exception("MD5 verify failure", md5); } EasyUtils.post(() -> { @@ -123,13 +135,11 @@ protected void onResponse(Response response) throws Exception { mListener.onEnd(mFile); } }); - - EasyUtils.closeStream(inputStream); - EasyUtils.closeStream(outputStream); } @Override protected void onFailure(final Exception e) { + // 打印错误堆栈 EasyLog.print(e); EasyUtils.post(() -> { if (mListener != null && HttpLifecycleControl.isLifecycleActive(getLifecycleOwner())) { diff --git a/library/src/main/java/com/hjq/http/config/ILogStrategy.java b/library/src/main/java/com/hjq/http/config/ILogStrategy.java index f31c3bc..4ebe29d 100644 --- a/library/src/main/java/com/hjq/http/config/ILogStrategy.java +++ b/library/src/main/java/com/hjq/http/config/ILogStrategy.java @@ -36,20 +36,20 @@ default void print() { void print(String key, String value); /** - * 将字符串格式化成JSON的格式 + * 将字符串格式化成 JSON 格式 */ - static String stringToJSON(String strJson) { - if (strJson == null) { - return null; + static String formatJson(String json) { + if (json == null) { + return ""; } // 计数tab的个数 int tabNum = 0; StringBuilder builder = new StringBuilder(); - int length = strJson.length(); + int length = json.length(); char last = 0; for (int i = 0; i < length; i++) { - char c = strJson.charAt(i); + char c = json.charAt(i); if (c == '{') { tabNum++; builder.append(c).append("\n") @@ -63,14 +63,14 @@ static String stringToJSON(String strJson) { builder.append(c).append("\n") .append(getSpaceOrTab(tabNum)); } else if (c == ':') { - if (i > 0 && strJson.charAt(i - 1) == '"') { + if (i > 0 && json.charAt(i - 1) == '"') { builder.append(c).append(" "); } else { builder.append(c); } } else if (c == '[') { tabNum++; - char next = strJson.charAt(i + 1); + char next = json.charAt(i + 1); if (next == ']') { builder.append(c); } else { @@ -92,6 +92,9 @@ static String stringToJSON(String strJson) { return builder.toString(); } + /** + * 创建对应数量的制表符 + */ static String getSpaceOrTab(int tabNum) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < tabNum; i++) { diff --git a/library/src/main/java/com/hjq/http/config/LogStrategy.java b/library/src/main/java/com/hjq/http/config/LogStrategy.java index 1a0ed0c..183f9f7 100644 --- a/library/src/main/java/com/hjq/http/config/LogStrategy.java +++ b/library/src/main/java/com/hjq/http/config/LogStrategy.java @@ -20,7 +20,7 @@ public void print(String log) { @Override public void json(String json) { - String text = ILogStrategy.stringToJSON(json); + String text = ILogStrategy.formatJson(json); if (!TextUtils.isEmpty(text)) { // 打印 Json 数据最好换一行再打印会好看一点 text = " \n" + text; diff --git a/library/src/main/java/com/hjq/http/listener/HttpCallback.java b/library/src/main/java/com/hjq/http/listener/HttpCallback.java index e9adcc4..ed0173d 100644 --- a/library/src/main/java/com/hjq/http/listener/HttpCallback.java +++ b/library/src/main/java/com/hjq/http/listener/HttpCallback.java @@ -10,38 +10,38 @@ */ public class HttpCallback implements OnHttpListener { - private OnHttpListener mSource; + private final OnHttpListener mListener; - public HttpCallback(OnHttpListener source) { - mSource = source; + public HttpCallback(OnHttpListener listener) { + mListener = listener; } @Override public void onStart(Call call) { - if (mSource != null) { - mSource.onStart(call); + if (mListener != null) { + mListener.onStart(call); } } @SuppressWarnings("unchecked") @Override public void onSucceed(T result) { - if (mSource != null) { - mSource.onSucceed(result); + if (mListener != null) { + mListener.onSucceed(result); } } @Override public void onFail(Exception e) { - if (mSource != null) { - mSource.onFail(e); + if (mListener != null) { + mListener.onFail(e); } } @Override public void onEnd(Call call) { - if (mSource != null) { - mSource.onEnd(call); + if (mListener != null) { + mListener.onEnd(call); } } } diff --git a/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java b/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java index 9ed5a3b..3b1b476 100644 --- a/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java +++ b/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java @@ -15,10 +15,20 @@ public interface OnDownloadListener { */ void onStart(File file); + /** + * 下载字节改变 + * + * @param totalByte 总字节数 + * @param downloadByte 已下载字节数 + */ + default void onByte(File file, long totalByte, long downloadByte) {} + /** * 下载进度改变 + * + * @param progress 下载进度值(0-100) */ - void onProgress(File file, long totalByte, long downloadByte, int progress); + void onProgress(File file, int progress); /** * 下载完成 diff --git a/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java b/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java index bb0573f..294d088 100644 --- a/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java +++ b/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java @@ -9,11 +9,17 @@ public interface OnUpdateListener extends OnHttpListener { /** - * 上传进度发生变化 + * 上传字节改变 + * + * @param totalByte 总字节数 + * @param updateByte 已上传字节数 + */ + default void onByte(long totalByte, long updateByte) {} + + /** + * 上传进度改变 * - * @param totalByte 总字节数 - * @param updateByte 已上传字节数 * @param progress 上传进度值(0-100) */ - void onUpdate(long totalByte, long updateByte, int progress); + void onProgress(int progress); } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/model/DownloadInfo.java b/library/src/main/java/com/hjq/http/model/DownloadInfo.java deleted file mode 100644 index f281336..0000000 --- a/library/src/main/java/com/hjq/http/model/DownloadInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hjq.http.model; - -import com.hjq.http.EasyUtils; - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/EasyHttp - * time : 2019/05/19 - * desc : 下载信息 - */ -public final class DownloadInfo { - - /** 总字节数 */ - private long mTotalByte; - - /** 已下载字节数 */ - private long mDownloadByte; - - public long getTotalByte() { - // 如果没有获取到下载内容的大小,就直接返回已下载字节大小 - if (mTotalByte <= 0) { - return mDownloadByte; - } - return mTotalByte; - } - - public void setTotalByte(long size) { - mTotalByte = size; - } - - public long getDownloadByte() { - return mDownloadByte; - } - - public void setDownloadByte(long size) { - mDownloadByte = size; - } - - /** - * 获取当前进度 - */ - public int getDownloadProgress() { - return EasyUtils.getProgressPercent(mTotalByte, mDownloadByte); - } -} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/model/HttpHeaders.java b/library/src/main/java/com/hjq/http/model/HttpHeaders.java index d50d131..b0b676b 100644 --- a/library/src/main/java/com/hjq/http/model/HttpHeaders.java +++ b/library/src/main/java/com/hjq/http/model/HttpHeaders.java @@ -13,6 +13,7 @@ */ public final class HttpHeaders { + /** 请求头存放集合 */ private HashMap mHeaders = EasyConfig.getInstance().getHeaders(); public void put(String key, String value) { diff --git a/library/src/main/java/com/hjq/http/model/HttpMethod.java b/library/src/main/java/com/hjq/http/model/HttpMethod.java index 7fbb400..a811fc9 100644 --- a/library/src/main/java/com/hjq/http/model/HttpMethod.java +++ b/library/src/main/java/com/hjq/http/model/HttpMethod.java @@ -28,15 +28,16 @@ public enum HttpMethod { /** Patch 请求 */ PATCH("PATCH"); - private final String method; + /** 请求方式 */ + private final String mMethod; HttpMethod(String method) { - this.method = method; + this.mMethod = method; } @NonNull @Override public String toString() { - return method; + return mMethod; } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/model/HttpParams.java b/library/src/main/java/com/hjq/http/model/HttpParams.java index 576b66b..745e507 100644 --- a/library/src/main/java/com/hjq/http/model/HttpParams.java +++ b/library/src/main/java/com/hjq/http/model/HttpParams.java @@ -13,6 +13,7 @@ */ public final class HttpParams { + /** 请求参数存放集合 */ private HashMap mParams = EasyConfig.getInstance().getParams(); /** 是否有流参数 */ diff --git a/library/src/main/java/com/hjq/http/model/DataClass.java b/library/src/main/java/com/hjq/http/model/ResponseClass.java similarity index 82% rename from library/src/main/java/com/hjq/http/model/DataClass.java rename to library/src/main/java/com/hjq/http/model/ResponseClass.java index 3d547c1..6f75471 100644 --- a/library/src/main/java/com/hjq/http/model/DataClass.java +++ b/library/src/main/java/com/hjq/http/model/ResponseClass.java @@ -6,4 +6,4 @@ * time : 2020/08/14 * desc : 数据解析模型类 */ -public abstract class DataClass {} \ No newline at end of file +public abstract class ResponseClass {} \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/BaseRequest.java b/library/src/main/java/com/hjq/http/request/BaseRequest.java index 98d0b1f..75dd2b9 100644 --- a/library/src/main/java/com/hjq/http/request/BaseRequest.java +++ b/library/src/main/java/com/hjq/http/request/BaseRequest.java @@ -20,9 +20,9 @@ import com.hjq.http.listener.OnHttpListener; import com.hjq.http.model.BodyType; import com.hjq.http.model.CallProxy; -import com.hjq.http.model.DataClass; import com.hjq.http.model.HttpHeaders; import com.hjq.http.model.HttpParams; +import com.hjq.http.model.ResponseClass; import java.lang.reflect.Field; import java.util.List; @@ -64,11 +64,12 @@ public abstract class BaseRequest { /** 请求标记 */ private String mTag; - public BaseRequest(LifecycleOwner lifecycle) { - if (lifecycle == null) { + public BaseRequest(LifecycleOwner lifecycleOwner) { + if (lifecycleOwner == null) { throw new IllegalArgumentException("are you ok?"); } - mLifecycleOwner = lifecycle; + mLifecycleOwner = lifecycleOwner; + tag(lifecycleOwner); } public T api(Class api) { @@ -131,7 +132,7 @@ public T server(IRequestServer server) { */ public T tag(Object tag) { if (tag != null) { - return tag(tag.toString()); + return tag(String.valueOf(tag)); } return (T) this; } @@ -149,7 +150,10 @@ public T client(OkHttpClient client) { return (T) this; } - public Call create() { + /** + * 创建连接对象 + */ + protected Call createCall() { BodyType type = mRequestType.getType(); @@ -157,7 +161,6 @@ public Call create() { HttpHeaders headers = new HttpHeaders(); Field[] fields = mRequestApi.getClass().getDeclaredFields(); - params.setMultipart(EasyUtils.isMultipart(fields)); // 如果参数中包含流参数并且当前请求方式不是表单的话 if (params.isMultipart() && type != BodyType.FORM) { @@ -168,21 +171,29 @@ public Call create() { for (Field field : fields) { // 允许访问私有字段 field.setAccessible(true); - // 规避非静态内部类持有的外部类对象 - if (mRequestApi.getClass().toString().startsWith(field.getType().toString())) { - continue; - } try { // 获取字段的对象 Object value = field.get(mRequestApi); + // 前提是这个字段值不能为空(基本数据类型有默认的值,而对象默认的值为 null) + if (EasyUtils.isEmpty(value)) { + // 遍历下一个字段 + continue; + } + // 获取字段的名称 String key; - if (field.isAnnotationPresent(HttpRename.class)) { - key = field.getAnnotation(HttpRename.class).value(); + HttpRename annotation = field.getAnnotation(HttpRename.class); + if (annotation != null) { + key = annotation.value(); } else { key = field.getName(); + // 如果是内部类则会出现一个字段名为 this$0 的外部类对象,会导致无限递归,这里要忽略掉,如果使用静态内部类则不会出现这个问题 + // 和规避 Kotlin 自动生成的伴生对象:https://github.com/getActivity/EasyHttp/issues/15 + if (key.matches("this\\$\\d+") || "Companion".equals(key)) { + continue; + } } // 如果这个字段需要忽略,则进行忽略 @@ -192,13 +203,6 @@ public Call create() { } else { params.remove(key); } - // 遍历下一个字段 - continue; - } - - // 前提是这个字段值不能为空(基本数据类型有默认的值,而对象默认的值为 null) - if (EasyUtils.isEmpty(value)) { - // 遍历下一个字段 continue; } @@ -208,44 +212,46 @@ public Call create() { Map map = ((Map) value); for (Object o : map.keySet()) { if (o != null && map.get(o) != null) { - headers.put(o.toString(), map.get(o).toString()); + headers.put(String.valueOf(o), String.valueOf(map.get(o))); } } } else { - headers.put(key, value.toString()); + headers.put(key, String.valueOf(value)); } - } else { - switch (type) { - case FORM: - if (value instanceof Map) { - Map map = ((Map) value); - for (Object o : map.keySet()) { - if (o != null && map.get(o) != null) { - params.put(o.toString(), map.get(o)); - } + continue; + } + + // 否则这就是一个普通的参数 + switch (type) { + case FORM: + if (value instanceof Map) { + Map map = ((Map) value); + for (Object o : map.keySet()) { + if (o != null && map.get(o) != null) { + params.put(String.valueOf(o), map.get(o)); } - } else { - params.put(key, value); } - break; - case JSON: - if (value instanceof List) { - // 如果这是一个 List 参数 - params.put(key, EasyUtils.listToJsonArray(((List) value))); - } else if (value instanceof Map) { - // 如果这是一个 Map 参数 - params.put(key, EasyUtils.mapToJsonObject(((Map) value))); - } else if (EasyUtils.isBeanType(value)) { - // 如果这是一个 Bean 参数 - params.put(key, EasyUtils.mapToJsonObject(EasyUtils.beanToHashMap(value))); - } else { - // 如果这是一个普通的参数 - params.put(key, value); - } - break; - default: - break; - } + } else { + params.put(key, value); + } + break; + case JSON: + if (value instanceof List) { + // 如果这是一个 List 参数 + params.put(key, EasyUtils.listToJsonArray(((List) value))); + } else if (value instanceof Map) { + // 如果这是一个 Map 参数 + params.put(key, EasyUtils.mapToJsonObject(((Map) value))); + } else if (EasyUtils.isBeanType(value)) { + // 如果这是一个 Bean 参数 + params.put(key, EasyUtils.mapToJsonObject(EasyUtils.beanToHashMap(value))); + } else { + // 如果这是一个普通的参数 + params.put(key, value); + } + break; + default: + break; } } catch (IllegalAccessException e) { @@ -258,15 +264,15 @@ public Call create() { if (interceptor != null) { interceptor.intercept(url, mTag, params, headers); } - return mClient.newCall(create(url, mTag, params, headers, type)); + return mClient.newCall(createRequest(url, mTag, params, headers, type)); } /** * 执行异步请求 */ - public T request(OnHttpListener listener) { - mCallProxy = new CallProxy(create()); - mCallProxy.enqueue(new NormalCallback(getLifecycle(), mCallProxy, listener)); + public T request(OnHttpListener listener) { + mCallProxy = new CallProxy(createCall()); + mCallProxy.enqueue(new NormalCallback(getLifecycleOwner(), mCallProxy, listener)); return (T) this; } @@ -276,13 +282,13 @@ public T request(OnHttpListener listener) { * @return 返回解析完成的对象 * @throws Exception 如果请求失败或者解析失败则抛出异常 */ - public T execute(DataClass t) throws Exception { + public T execute(ResponseClass t) throws Exception { try { - mCallProxy = new CallProxy(create()); + mCallProxy = new CallProxy(createCall()); Response response = mCallProxy.execute(); - return (T) EasyConfig.getInstance().getHandler().requestSucceed(getLifecycle(), response, EasyUtils.getReflectType(t)); + return (T) EasyConfig.getInstance().getHandler().requestSucceed(getLifecycleOwner(), response, EasyUtils.getReflectType(t)); } catch (Exception e) { - throw EasyConfig.getInstance().getHandler().requestFail(getLifecycle(), e); + throw EasyConfig.getInstance().getHandler().requestFail(getLifecycleOwner(), e); } } @@ -296,11 +302,20 @@ public T cancel() { return (T) this; } - protected LifecycleOwner getLifecycle() { + /** + * 获取生命周期管控对象 + */ + protected LifecycleOwner getLifecycleOwner() { return mLifecycleOwner; } - protected abstract String getMethod(); + /** + * 获取请求的方式 + */ + protected abstract String getRequestMethod(); - protected abstract Request create(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type); + /** + * 创建请求的对象 + */ + protected abstract Request createRequest(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type); } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/BodyRequest.java b/library/src/main/java/com/hjq/http/request/BodyRequest.java index b6acf70..c920692 100644 --- a/library/src/main/java/com/hjq/http/request/BodyRequest.java +++ b/library/src/main/java/com/hjq/http/request/BodyRequest.java @@ -5,8 +5,9 @@ import com.hjq.http.EasyConfig; import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; -import com.hjq.http.body.JsonObjectBody; -import com.hjq.http.body.MultipartBodyProxy; +import com.hjq.http.body.JsonBody; +import com.hjq.http.body.ProgressBody; +import com.hjq.http.body.StringBody; import com.hjq.http.body.UpdateBody; import com.hjq.http.listener.OnHttpListener; import com.hjq.http.listener.OnUpdateListener; @@ -28,27 +29,33 @@ * author : Android 轮子哥 * github : https://github.com/getActivity/EasyHttp * time : 2020/10/07 - * desc : Post 请求 + * desc : 带 RequestBody 请求 */ +@SuppressWarnings("unchecked") public abstract class BodyRequest extends BaseRequest { - private OnUpdateListener mListener; + private OnUpdateListener mUpdateListener; private RequestBody mRequestBody; - public BodyRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public BodyRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } - /** - * 自定义请求参数的 Map - */ public T body(Map map) { - return body(new JsonObjectBody(map)); + return body(new JsonBody(map)); + } + + public T body(List list) { + return body(new JsonBody(list)); + } + + public T body(String text) { + return body(new StringBody(text)); } /** - * 自定义请求 Body + * 自定义 RequestBody */ public T body(RequestBody body) { mRequestBody = body; @@ -56,12 +63,12 @@ public T body(RequestBody body) { } @Override - protected Request create(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { + protected Request createRequest(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { Request.Builder request = new Request.Builder(); request.url(url); EasyLog.print("RequestUrl", url); - EasyLog.print("RequestMethod", getMethod()); + EasyLog.print("RequestMethod", getRequestMethod()); if (tag != null) { request.tag(tag); @@ -74,76 +81,10 @@ protected Request create(String url, String tag, HttpParams params, HttpHeaders } } - RequestBody body = mRequestBody; - if (mRequestBody == null) { - if (params.isMultipart() && !params.isEmpty()) { - MultipartBodyProxy.Builder builder = new MultipartBodyProxy.Builder(); - builder.setType(MultipartBody.FORM); - builder.setLifecycleOwner(getLifecycle()); - builder.setOnUpdateListener(mListener); - for (String key : params.getNames()) { - Object object = params.get(key); - if (object instanceof File) { - // 如果这是一个文件 - MultipartBody.Part part = MultipartBodyProxy.createPart(key, (File) object); - if (part != null) { - builder.addPart(part); - } - } else if (object instanceof InputStream) { - // 如果这是一个输入流 - MultipartBody.Part part = MultipartBodyProxy.createPart(key, (InputStream) object); - if (part != null) { - builder.addPart(part); - } - } else if (object instanceof RequestBody) { - // 如果这是一个自定义 RequestBody - if (object instanceof UpdateBody) { - builder.addFormDataPart(key, EasyUtils.encodeString(((UpdateBody) object).getName()), (RequestBody) object); - } else { - builder.addFormDataPart(key, null, (RequestBody) object); - } - } else { - if (object instanceof List && EasyUtils.isFileList((List) object)) { - // 上传文件列表 - for (Object item : (List) object) { - MultipartBody.Part part = MultipartBodyProxy.createPart(key, (File) item); - if (part != null) { - builder.addPart(part); - } - } - } else { - // 如果这是一个普通参数 - builder.addFormDataPart(key, object.toString()); - } - } - } - try { - body = builder.build(); - } catch (IllegalStateException ignore) { - // 如果里面没有任何参数会抛出异常 - // java.lang.IllegalStateException: Multipart body must have at least one part. - body = new FormBody.Builder().build(); - } - } else { - if (type == BodyType.JSON) { - if (!params.isEmpty()) { - body = new JsonObjectBody(params.getParams()); - } else { - body = new JsonObjectBody(); - } - } else { - FormBody.Builder builder = new FormBody.Builder(); - if (!params.isEmpty()) { - for (String key : params.getNames()) { - builder.add(key, params.get(key).toString()); - } - } - body = builder.build(); - } - } - } - request.method(getMethod(), body); + RequestBody body = mRequestBody != null ? mRequestBody : createBody(params, type); + request.method(getRequestMethod(), body); + // 打印请求头和参数的日志 if (EasyConfig.getInstance().isLogEnabled()) { if (!headers.isEmpty() || !params.isEmpty()) { @@ -158,17 +99,24 @@ protected Request create(String url, String tag, HttpParams params, HttpHeaders EasyLog.print(); } - if (body instanceof JsonObjectBody) { - EasyLog.json(((JsonObjectBody) body).getJsonObject().toString()); - } else { + if (body instanceof FormBody || + body instanceof MultipartBody || + body instanceof ProgressBody) { + // 打印表单 for (String key : params.getNames()) { Object value = params.get(key); if (value instanceof String) { - EasyLog.print(key, "\"" + value.toString() + "\""); + EasyLog.print(key, "\"" + value + "\""); } else { - EasyLog.print(key, value.toString()); + EasyLog.print(key, String.valueOf(value)); } } + } else if (body instanceof JsonBody) { + // 打印 Json + EasyLog.json(body.toString()); + } else { + // 打印文本 + EasyLog.print(body.toString()); } if (!headers.isEmpty() || !params.isEmpty()) { @@ -183,10 +131,91 @@ protected Request create(String url, String tag, HttpParams params, HttpHeaders * 执行异步请求(执行传入上传进度监听器) */ @Override - public T request(OnHttpListener listener) { + public T request(OnHttpListener listener) { if (listener instanceof OnUpdateListener) { - mListener = (OnUpdateListener) listener; + mUpdateListener = (OnUpdateListener) listener; } return super.request(listener); } + + /** + * 组装 RequestBody 对象 + */ + private RequestBody createBody(HttpParams params, BodyType type) { + if (params.isMultipart() && !params.isEmpty()) { + MultipartBody.Builder builder = new MultipartBody.Builder(); + builder.setType(MultipartBody.FORM); + for (String key : params.getNames()) { + Object object = params.get(key); + + // 如果这是一个文件 + if (object instanceof File) { + MultipartBody.Part part = EasyUtils.createPart(key, (File) object); + if (part != null) { + builder.addPart(part); + } + continue; + } + + // 如果这是一个输入流 + if (object instanceof InputStream) { + MultipartBody.Part part = EasyUtils.createPart(key, (InputStream) object); + if (part != null) { + builder.addPart(part); + } + continue; + } + + // 如果这是一个自定义 RequestBody + if (object instanceof RequestBody) { + if (object instanceof UpdateBody) { + builder.addFormDataPart(key, EasyUtils.encodeString(((UpdateBody) object).getName()), (RequestBody) object); + } else { + builder.addFormDataPart(key, null, (RequestBody) object); + } + continue; + } + + // 上传文件列表 + if (object instanceof List && EasyUtils.isFileList((List) object)) { + for (Object item : (List) object) { + MultipartBody.Part part = EasyUtils.createPart(key, (File) item); + if (part != null) { + builder.addPart(part); + } + } + continue; + } + + // 如果这是一个普通参数 + builder.addFormDataPart(key, String.valueOf(object)); + } + + if (mUpdateListener != null) { + return new ProgressBody(builder.build(), getLifecycleOwner(), mUpdateListener); + } else { + return builder.build(); + } + } + + if (type == BodyType.JSON) { + if (mUpdateListener != null) { + return new ProgressBody(new JsonBody(params.getParams()), getLifecycleOwner(), mUpdateListener); + } else { + return new JsonBody(params.getParams()); + } + } + + FormBody.Builder builder = new FormBody.Builder(); + if (!params.isEmpty()) { + for (String key : params.getNames()) { + builder.add(key, String.valueOf(params.get(key))); + } + } + if (mUpdateListener != null) { + return new ProgressBody(builder.build(), getLifecycleOwner(), mUpdateListener); + } else { + return builder.build(); + } + } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/DeleteRequest.java b/library/src/main/java/com/hjq/http/request/DeleteRequest.java index 05dc627..4ccb9f1 100644 --- a/library/src/main/java/com/hjq/http/request/DeleteRequest.java +++ b/library/src/main/java/com/hjq/http/request/DeleteRequest.java @@ -12,12 +12,12 @@ */ public final class DeleteRequest extends BodyRequest { - public DeleteRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public DeleteRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.DELETE.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/DownloadRequest.java b/library/src/main/java/com/hjq/http/request/DownloadRequest.java index 0647c87..5993404 100644 --- a/library/src/main/java/com/hjq/http/request/DownloadRequest.java +++ b/library/src/main/java/com/hjq/http/request/DownloadRequest.java @@ -9,10 +9,10 @@ import com.hjq.http.listener.OnHttpListener; import com.hjq.http.model.BodyType; import com.hjq.http.model.CallProxy; -import com.hjq.http.model.DataClass; import com.hjq.http.model.HttpHeaders; import com.hjq.http.model.HttpMethod; import com.hjq.http.model.HttpParams; +import com.hjq.http.model.ResponseClass; import java.io.File; @@ -41,8 +41,8 @@ public final class DownloadRequest extends BaseRequest { /** 请求执行对象 */ private CallProxy mCallProxy; - public DownloadRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public DownloadRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } /** @@ -92,14 +92,14 @@ public DownloadRequest listener(OnDownloadListener listener) { } @Override - protected Request create(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { + protected Request createRequest(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { switch (mMethod) { case GET: // 如果这个下载请求方式是 Get - return new GetRequest(getLifecycle()).create(url, tag, params, headers, type); + return new GetRequest(getLifecycleOwner()).createRequest(url, tag, params, headers, type); case POST: // 如果这个下载请求方式是 Post - return new PostRequest(getLifecycle()).create(url, tag, params, headers, type); + return new PostRequest(getLifecycleOwner()).createRequest(url, tag, params, headers, type); default: throw new IllegalStateException("are you ok?"); } @@ -109,9 +109,9 @@ protected Request create(String url, String tag, HttpParams params, HttpHeaders * 开始下载 */ public DownloadRequest start() { - mCallProxy = new CallProxy(create()); + mCallProxy = new CallProxy(createCall()); /** 下载回调对象 */ - mCallProxy.enqueue(new DownloadCallback(getLifecycle(), mCallProxy, mFile, mMd5, mListener)); + mCallProxy.enqueue(new DownloadCallback(getLifecycleOwner(), mCallProxy, mFile, mMd5, mListener)); return this; } @@ -132,7 +132,7 @@ public DownloadRequest request(OnHttpListener listener) { } @Override - public T execute(DataClass t) { + public T execute(ResponseClass t) { // 请调用 start 方法 throw new IllegalStateException("are you ok?"); } @@ -144,7 +144,7 @@ public DownloadRequest cancel() { } @Override - protected String getMethod() { - return mMethod.toString(); + protected String getRequestMethod() { + return String.valueOf(mMethod); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/GetRequest.java b/library/src/main/java/com/hjq/http/request/GetRequest.java index 7bfd6e7..74f0d18 100644 --- a/library/src/main/java/com/hjq/http/request/GetRequest.java +++ b/library/src/main/java/com/hjq/http/request/GetRequest.java @@ -12,12 +12,12 @@ */ public final class GetRequest extends UrlRequest { - public GetRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public GetRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.GET.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/HeadRequest.java b/library/src/main/java/com/hjq/http/request/HeadRequest.java index 86ea3ac..343a7a5 100644 --- a/library/src/main/java/com/hjq/http/request/HeadRequest.java +++ b/library/src/main/java/com/hjq/http/request/HeadRequest.java @@ -12,12 +12,12 @@ */ public final class HeadRequest extends UrlRequest { - public HeadRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public HeadRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.HEAD.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/PatchRequest.java b/library/src/main/java/com/hjq/http/request/PatchRequest.java index d5c6721..61246e4 100644 --- a/library/src/main/java/com/hjq/http/request/PatchRequest.java +++ b/library/src/main/java/com/hjq/http/request/PatchRequest.java @@ -12,12 +12,12 @@ */ public final class PatchRequest extends BodyRequest { - public PatchRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public PatchRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.PATCH.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/PostRequest.java b/library/src/main/java/com/hjq/http/request/PostRequest.java index f42b09b..ffedfe8 100644 --- a/library/src/main/java/com/hjq/http/request/PostRequest.java +++ b/library/src/main/java/com/hjq/http/request/PostRequest.java @@ -12,12 +12,12 @@ */ public final class PostRequest extends BodyRequest { - public PostRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public PostRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.POST.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/PutRequest.java b/library/src/main/java/com/hjq/http/request/PutRequest.java index 1b2c5c1..6fad20a 100644 --- a/library/src/main/java/com/hjq/http/request/PutRequest.java +++ b/library/src/main/java/com/hjq/http/request/PutRequest.java @@ -12,12 +12,12 @@ */ public final class PutRequest extends BodyRequest { - public PutRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public PutRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } @Override - protected String getMethod() { + protected String getRequestMethod() { return HttpMethod.PUT.toString(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/request/UrlRequest.java b/library/src/main/java/com/hjq/http/request/UrlRequest.java index 9e49d76..092a524 100644 --- a/library/src/main/java/com/hjq/http/request/UrlRequest.java +++ b/library/src/main/java/com/hjq/http/request/UrlRequest.java @@ -15,14 +15,15 @@ * author : Android 轮子哥 * github : https://github.com/getActivity/EasyHttp * time : 2020/10/07 - * desc : url 类型请求 + * desc : 不带 RequestBody 的请求 */ +@SuppressWarnings("unchecked") public abstract class UrlRequest extends BaseRequest { private CacheControl mCacheControl; - public UrlRequest(LifecycleOwner lifecycle) { - super(lifecycle); + public UrlRequest(LifecycleOwner lifecycleOwner) { + super(lifecycleOwner); } /** @@ -34,7 +35,7 @@ public T cache(CacheControl cacheControl) { } @Override - protected Request create(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { + protected Request createRequest(String url, String tag, HttpParams params, HttpHeaders headers, BodyType type) { Request.Builder request = new Request.Builder(); if (mCacheControl != null) { request.cacheControl(mCacheControl); @@ -55,15 +56,15 @@ protected Request create(String url, String tag, HttpParams params, HttpHeaders // 添加参数 if (!params.isEmpty()) { for (String key : params.getNames()) { - builder.addEncodedQueryParameter(key, params.get(key).toString()); + builder.addEncodedQueryParameter(key, String.valueOf(params.get(key))); } } HttpUrl link = builder.build(); request.url(link); - request.method(getMethod(), null); + request.method(getRequestMethod(), null); - EasyLog.print("RequestUrl", link.toString()); - EasyLog.print("RequestMethod", getMethod()); + EasyLog.print("RequestUrl", String.valueOf(link)); + EasyLog.print("RequestMethod", getRequestMethod()); return request.build(); } } \ No newline at end of file