From a7773b61790e08e486ddf507bed7959e771fd6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Android=20=E8=BD=AE=E5=AD=90=E5=93=A5?= Date: Sun, 12 Nov 2023 00:35:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20Protobuf=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BD=BF=E7=94=A8=E6=96=87=E6=A1=A3=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=A1=86=E6=9E=B6=E4=B8=AD=E7=9B=B8=E5=85=B3=20Reques?= =?UTF-8?q?tBody=20=E7=B1=BB=E5=91=BD=E5=90=8D=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E4=B8=AD=E4=BB=A3=E7=A0=81=E5=B5=8C=E5=A5=97?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=8F=8A=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20=E4=BF=AE=E6=AD=A3=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=E6=8A=9B=20Exception=20=E6=88=90=E6=8A=9B=20Throwable=20?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=20=E4=BF=AE=E6=AD=A3=20Post=20Json=20Request?= =?UTF-8?q?Body=20=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HelpDoc.md | 261 ++++++++++++++++-- README.md | 10 +- app/build.gradle | 12 +- .../com/hjq/easy/demo/AppApplication.java | 38 ++- .../java/com/hjq/easy/demo/BaseActivity.java | 7 +- .../java/com/hjq/easy/demo/MainActivity.java | 12 +- .../easy/demo/http/model/RequestHandler.java | 49 ++-- .../main/res/xml/network_security_config.xml | 14 +- build.gradle | 2 +- library/build.gradle | 4 +- .../main/java/com/hjq/http/EasyConfig.java | 17 +- .../src/main/java/com/hjq/http/EasyHttp.java | 33 ++- .../src/main/java/com/hjq/http/EasyUtils.java | 10 +- .../com/hjq/http/body/CustomTypeBody.java | 2 +- .../{JsonBody.java => JsonRequestBody.java} | 20 +- ...y.java => ProgressMonitorRequestBody.java} | 33 +-- .../{TextBody.java => TextRequestBody.java} | 9 +- ...Body.java => UpdateStreamRequestBody.java} | 10 +- ...apperBody.java => WrapperRequestBody.java} | 6 +- .../com/hjq/http/callback/BaseCallback.java | 15 +- .../hjq/http/callback/DownloadCallback.java | 76 +++-- .../com/hjq/http/callback/NormalCallback.java | 55 ++-- .../com/hjq/http/config/IRequestHandler.java | 21 +- .../config/impl/RequestFormBodyStrategy.java | 12 +- .../config/impl/RequestJsonBodyStrategy.java | 4 +- .../http/lifecycle/HttpLifecycleManager.java | 3 +- .../hjq/http/listener/HttpCallbackProxy.java | 4 +- .../hjq/http/listener/OnDownloadListener.java | 2 +- .../com/hjq/http/listener/OnHttpListener.java | 2 +- .../hjq/http/listener/OnUpdateListener.java | 6 +- .../hjq/http/model/FileContentResolver.java | 6 +- .../java/com/hjq/http/model/HttpHeaders.java | 6 +- .../java/com/hjq/http/model/HttpParams.java | 6 +- .../com/hjq/http/request/BodyRequest.java | 36 +-- .../hjq/http/request/DeleteBodyRequest.java | 3 +- ...leteRequest.java => DeleteUrlRequest.java} | 7 +- .../com/hjq/http/request/HttpRequest.java | 39 ++- .../java/com/hjq/http/request/UrlRequest.java | 6 +- .../hjq/http/ssl/UnSafeHostnameVerifier.java | 7 +- 39 files changed, 546 insertions(+), 319 deletions(-) rename library/src/main/java/com/hjq/http/body/{JsonBody.java => JsonRequestBody.java} (84%) rename library/src/main/java/com/hjq/http/body/{ProgressBody.java => ProgressMonitorRequestBody.java} (69%) rename library/src/main/java/com/hjq/http/body/{TextBody.java => TextRequestBody.java} (89%) rename library/src/main/java/com/hjq/http/body/{UpdateBody.java => UpdateStreamRequestBody.java} (83%) rename library/src/main/java/com/hjq/http/body/{WrapperBody.java => WrapperRequestBody.java} (89%) rename library/src/main/java/com/hjq/http/request/{DeleteRequest.java => DeleteUrlRequest.java} (75%) diff --git a/HelpDoc.md b/HelpDoc.md index dffce8d..8bf4eb6 100644 --- a/HelpDoc.md +++ b/HelpDoc.md @@ -112,6 +112,14 @@ * [对返回的数据进行包装](#对返回的数据进行包装) +* [支持 Protobuf](#支持-protobuf) + + * [准备工作](#准备工作) + + * [请求体解析成 Protobuf](#请求体解析成-protobuf) + + * [响应体解析支持 Protobuf](#响应体解析支持-protobuf) + # 集成文档 #### 配置权限 @@ -365,7 +373,7 @@ EasyHttp.post(this) } @Override - public void onUpdateFail(Exception e) { + public void onUpdateFail(Throwable throwable) { toast("上传失败"); } @@ -410,8 +418,8 @@ EasyHttp.download(this) } @Override - public void onDownloadFail(File file, Exception e) { - toast("下载出错:" + e.getMessage()); + public void onDownloadFail(File file, Throwable throwable) { + toast("下载出错:" + throwable.getMessage()); } @Override @@ -465,8 +473,8 @@ try { .setKeyword("搬砖不再有")) .execute(new ResponseClass>() {}); toast("请求成功,请看日志"); -} catch (Exception e) { - toast(e.getMessage()); +} catch (Throwable throwable) { + toast(throwable.getMessage()); } ``` @@ -647,8 +655,8 @@ lifecycleScope.launch(Dispatchers.IO) { withContext(Dispatchers.Main) { // 在这里进行 UI 刷新 } - } catch (e: Exception) { - toast(e.message) + } catch (throwable: Throwable) { + toast(throwable.message) } } ``` @@ -991,6 +999,8 @@ public final class XxxApi implements IRequestApi { #### 如何传入请求头 +* 给字段加上 `@HttpHeader` 注解即可,则表示这个字段是一个请求头,如果没有加上此注解,则框架默认将字段作为请求参数 + ```java public final class XxxApi implements IRequestApi { @@ -1007,6 +1017,8 @@ public final class XxxApi implements IRequestApi { #### 如何重命名参数或者请求头的名称 +* 给字段加上 `@HttpRename` 注解即可,则可以修改参数名的值,如果没有加上此注解,则框架默认使用字段名作为参数名 + ```java public final class XxxApi implements IRequestApi { @@ -1156,12 +1168,12 @@ EasyConfig.with(okHttpClient) #### 如何取消已发起的请求 ```java -// 取消和这个 LifecycleOwner 关联的请求 -EasyHttp.cancel(LifecycleOwner lifecycleOwner); +// 根据 TAG 取消请求任务 +EasyHttp.cancelByTag(Object tag); // 取消指定 Tag 标记的请求 -EasyHttp.cancel(Object tag); +EasyHttp.cancelByTag(Object tag); // 取消所有请求 -EasyHttp.cancel(); +EasyHttp.cancelAll(); ``` #### 如何延迟发起一个请求 @@ -1296,7 +1308,7 @@ EasyHttp.post(ApplicationLifecycle.getInstance()) } @Override - public void onHttpFail(Exception e) { + public void onHttpFail(Throwable throwable) { } }); @@ -1307,7 +1319,7 @@ EasyHttp.post(ApplicationLifecycle.getInstance()) * 除了 Application,如果你在 Activity 或者 Service 中采用了 ApplicationLifecycle 的写法,那么为了避免内存泄漏或者崩溃的事情发生,需要你在请求的时候设置对应的 Tag,然后在恰当的时机手动取消请求(一般在 Activity 或者 Service 销毁或者退出的时候取消请求)。 ```java -EasyHttp.cancel("abc"); +EasyHttp.cancelByTag("abc"); ``` #### 如何在 ViewModel 中使用 EasyHttp 请求网络 @@ -1354,7 +1366,7 @@ public class XxxViewModel extends BaseViewModel { } @Override - public void onHttpFail(Exception e) { + public void onHttpFail(Throwable throwable) { } }); @@ -1401,7 +1413,7 @@ EasyHttp.post(this) } @Override - public void onHttpFail(Exception e) { + public void onHttpFail(Throwable throwable) { } }); @@ -1419,7 +1431,7 @@ String json = gson.toJson(parameter); EasyHttp.post(this) .api(new XxxApi()) - .body(new JsonBody(json)) + .body(new JsonRequestBody(json)) .request(new HttpCallbackProxy>(this) { @Override @@ -1450,11 +1462,11 @@ parameter.put("key1", value1); parameter.put("key2", value2); String json = gson.toJson(parameter); -JsonBody jsonBody = new JsonBody(json) +JsonRequestBody jsonRequestBody = new JsonRequestBody(json) EasyHttp.post(this) .api(new XxxApi()) - .body(jsonBody) + .body(jsonRequestBody) .request(new HttpCallbackProxy>(this) { @Override @@ -1655,8 +1667,12 @@ Observable.create(new ObservableOnSubscribe>() { .api(new SearchBlogsApi() .setKeyword("搬砖不再有")) .execute(new ResponseClass>() {}); - } catch (Exception e) { - throw e; + } catch (Throwable throwable) { + if (throwable instanceof Exception) { + throw (Exception) throwable; + } else { + throw new RuntimeException(throwable); + } } HttpData data2; @@ -1665,8 +1681,12 @@ Observable.create(new ObservableOnSubscribe>() { .api(new SearchBlogsApi() .setKeyword(data1.getMessage())) .execute(new ResponseClass>() {}); - } catch (Exception e) { - throw e; + } catch (Throwable throwable) { + if (throwable instanceof Exception) { + throw (Exception) throwable; + } else { + throw new RuntimeException(throwable); + } } emitter.onNext(data2); @@ -1740,9 +1760,9 @@ Observable.create(new ObservableOnSubscribe>() { } @Override - public void onHttpFail(Exception e) { - super.onHttpFail(e); - emitter.onError(e); + public void onHttpFail(Throwable throwable) { + super.onHttpFail(throwable); + emitter.onError(throwable); } }); } @@ -1764,7 +1784,7 @@ Observable.create(new ObservableOnSubscribe>() { @Override public void accept(String s) throws Exception { - Log.i("EasyHttp", ""当前页码位置" + s); + Log.i("EasyHttp", "当前页码位置" + s); } }, new Consumer() { @@ -1774,4 +1794,193 @@ Observable.create(new ObservableOnSubscribe>() { toast(throwable.getMessage()); } }); +``` + +# 支持 Protobuf + +#### 准备工作 + +* 在项目根目录下得 `build.gradle` 文件加入以下配置 + +```groovy +buildscript { + + ...... + + dependencies { + // 自动生成 Protobuf 类插件:https://github.com/google/protobuf-gradle-plugin + classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.3' + } +} +``` + +* 在项目 app 模块下的 `build.gradle` 文件中加入远程依赖 + +```groovy +...... + +apply plugin: 'com.google.protobuf' + +android { + ...... + + sourceSets { + main { + proto { + // 指定 Protobuf 文件路径 + srcDir 'src/main/proto' + } + } + } +} + +protobuf { + + protoc { + // 也可以配置本地编译器路径 + artifact = 'com.google.protobuf:protoc:3.23.0' + } + + generateProtoTasks { + all().each { task -> + task.builtins { + remove java + } + task.builtins { + // 生产java源码 + java {} + } + } + } +} + +dependencies { + + ...... + + // Protobuf:https://github.com/protocolbuffers/protobuf + implementation 'com.google.protobuf:protobuf-java:3.23.1' + implementation 'com.google.protobuf:protoc:3.23.0' +} +``` + +* 在 `app/src/main/` 新建一个名为 `proto` 文件夹,用于存放 Protobuf 相关文件,然后创建 `Person.proto` 文件,具体内容如下: + +```text +syntax = "proto3"; +package tutorial; + +message Person { + string name = 1; + int32 id = 2; + string email = 3; + string phone = 4; +} +``` + +* 然后 `Rebuild Project`,就能看到插件自动生成的 `PersonOuterClass` 类,`PersonOuterClass` 类中还有一个名为 `Person` 的静态内部类 + +#### 请求体解析成 Protobuf + +* 创建一个自定义的 RequestBody 类,用于将 Protocol 对象解析成流,建议存放在 `com.xxx.xxx/http/model` 包名下, + +```java +public class ProtocolRequestBody extends RequestBody { + + /** MessageLite 对象 */ + private final MessageLite mMessageLite; + /** 字节数组 */ + private final byte[] mBytes; + + public ProtocolRequestBody(MessageLite messageLite) { + mMessageLite = messageLite; + mBytes = messageLite.toByteArray(); + } + + @Override + public MediaType contentType() { + return ContentType.JSON; + } + + @Override + public long contentLength() { + // 需要注意:这里需要用字节数组的长度来计算 + return mBytes.length; + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.write(mBytes, 0, mBytes.length); + } + + @NonNull + @Override + public String toString() { + return mMessageLite.toString(); + } + + /** + * 获取 MessageLite 对象 + */ + @NonNull + public MessageLite getMessageLite() { + return mMessageLite; + } +} +``` + +* 发起请求示例 + +```java +// 假装生成一个 Protobuf 对象 +Person person = Person.parseFrom("xxxxxxxxx".getBytes()); + +EasyHttp.post(this) + .api(new XxxApi()) + .body(new ProtocolRequestBody(person)) + .request(new HttpCallbackProxy>(this) { + + @Override + public void onHttpSuccess(HttpData result) { + + } + }); +``` + +#### 响应体解析支持 Protobuf + +* 这个支持很简单了,只需要修改 `IRequestHandler` 接口的实现即可,具体的代码实现如下: + +``` +public final class RequestHandler implements IRequestHandler { + + ...... + + @NonNull + @Override + public Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, + @NonNull Type type) throws Throwable { + ...... + + final Object result; + + try { + if (type instanceof Class && AbstractParser.class.isAssignableFrom((Class) type)) { + String simpleName = ((Class) type).getSimpleName(); + Class clazz = Class.forName("tutorial." + simpleName + ".OuterClass." + simpleName); + Method parseFromMethod = clazz.getMethod("parseFrom", byte[].class); + // 调用静态方法 + result = parseFromMethod.invoke(null, (Object) text.getBytes()); + } else { + result = GsonFactory.getSingletonGson().fromJson(text, type); + } + } catch (JsonSyntaxException e) { + // 返回结果读取异常 + throw new DataException(mApplication.getString(R.string.http_data_explain_error), e); + } + + ...... + return result; + } +} ``` \ No newline at end of file diff --git a/README.md b/README.md index 787297d..5d54276 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ * 博客地址:[网络请求,如斯优雅](https://www.jianshu.com/p/93cd59dec002) -* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处下载Demo](https://github.com/getActivity/EasyHttp/releases/download/12.5/EasyHttp.apk) +* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处下载Demo](https://github.com/getActivity/EasyHttp/releases/download/12.6/EasyHttp.apk) ![](picture/demo_code.png) @@ -61,7 +61,7 @@ android { dependencies { // 网络请求框架:https://github.com/getActivity/EasyHttp - implementation 'com.github.getActivity:EasyHttp:12.5' + implementation 'com.github.getActivity:EasyHttp:12.6' // OkHttp 框架:https://github.com/square/okhttp // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.13' @@ -84,9 +84,9 @@ dependencies { | 功能或细节 | [EasyHttp](https://github.com/getActivity/EasyHttp) | [Retrofit](https://github.com/square/retrofit) | [OkGo](https://github.com/jeasonlzy/okhttp-OkGo) | | :----: | :------: | :-----: | :-----: | -| 对应版本 | 12.5 | 2.9.0 | 3.0.4 | +| 对应版本 | 12.6 | 2.9.0 | 3.0.4 | | issues 数 | [![](https://img.shields.io/github/issues/getActivity/EasyHttp.svg)](https://github.com/getActivity/EasyHttp/issues) | [![](https://img.shields.io/github/issues/square/retrofit.svg)](https://github.com/square/retrofit/issues) | [![](https://img.shields.io/github/issues/jeasonlzy/okhttp-OkGo.svg)](https://github.com/jeasonlzy/okhttp-OkGo/issues) | -| **aar 包大小** | 92 KB | 123 KB | 131 KB | +| **aar 包大小** | 93 KB | 123 KB | 131 KB | | minSdk 要求 | API 14+ | API 21+ | API 14+ | | 配置多域名 | ✅ | ❌ | ✅ | | **动态 Host** | ✅ | ❌ | ❌ | @@ -187,7 +187,7 @@ public final class HttpLifecycleManager implements LifecycleEventObserver { // 移除监听 source.getLifecycle().removeObserver(this); // 取消请求 - EasyHttp.cancel(source); + EasyHttp.cancelByTag(source); } } ``` diff --git a/app/build.gradle b/app/build.gradle index aedabfb..83e5065 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId 'com.hjq.easy.demo' minSdkVersion 21 targetSdkVersion 31 - versionCode 1205 - versionName '12.5' + versionCode 1206 + versionName '12.6' } // 支持 JDK 1.8 @@ -76,7 +76,7 @@ dependencies { implementation 'com.github.getActivity:Toaster:12.5' // 权限请求框架:https://github.com/getActivity/XXPermissions - implementation 'com.github.getActivity:XXPermissions:18.3' + implementation 'com.github.getActivity:XXPermissions:18.5' // 标题栏框架:https://github.com/getActivity/TitleBar implementation 'com.github.getActivity:TitleBar:10.5' @@ -84,11 +84,15 @@ dependencies { // Json 解析框架:https://github.com/google/gson implementation 'com.google.code.gson:gson:2.10.1' // Gson 解析容错:https://github.com/getActivity/GsonFactory - implementation 'com.github.getActivity:GsonFactory:8.0' + implementation 'com.github.getActivity:GsonFactory:9.0' // 腾讯 MMKV:https://github.com/Tencent/MMKV implementation 'com.tencent:mmkv-static:1.2.14' + // Bugly 异常捕捉:https://bugly.qq.com/docs/user-guide/instruction-manual-android/?v=20190418140644 + implementation 'com.tencent.bugly:crashreport:4.1.9' + implementation 'com.tencent.bugly:nativecrashreport:3.9.2' + // 日志调试框架:https://github.com/getActivity/Logcat debugImplementation 'com.github.getActivity:Logcat:11.8' diff --git a/app/src/main/java/com/hjq/easy/demo/AppApplication.java b/app/src/main/java/com/hjq/easy/demo/AppApplication.java index 9c82ab8..d553b7f 100644 --- a/app/src/main/java/com/hjq/easy/demo/AppApplication.java +++ b/app/src/main/java/com/hjq/easy/demo/AppApplication.java @@ -1,12 +1,14 @@ package com.hjq.easy.demo; import android.app.Application; - import androidx.annotation.NonNull; - +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonToken; import com.hjq.easy.demo.http.model.RequestHandler; import com.hjq.easy.demo.http.server.ReleaseServer; import com.hjq.easy.demo.http.server.TestServer; +import com.hjq.gson.factory.GsonFactory; +import com.hjq.gson.factory.ParseExceptionCallback; import com.hjq.http.EasyConfig; import com.hjq.http.config.IRequestInterceptor; import com.hjq.http.config.IRequestServer; @@ -14,8 +16,8 @@ import com.hjq.http.model.HttpParams; import com.hjq.http.request.HttpRequest; import com.hjq.toast.Toaster; +import com.tencent.bugly.crashreport.CrashReport; import com.tencent.mmkv.MMKV; - import okhttp3.OkHttpClient; /** @@ -32,6 +34,36 @@ public void onCreate() { Toaster.init(this); MMKV.initialize(this); + // Bugly 异常捕捉 + CrashReport.initCrashReport(this, "8ca94a2408", BuildConfig.DEBUG); + + // 设置 Json 解析容错监听 + GsonFactory.setParseExceptionCallback(new ParseExceptionCallback() { + + @Override + public void onParseObjectException(TypeToken typeToken, String fieldName, JsonToken jsonToken) { + handlerGsonParseException("解析对象析异常:" + typeToken + "#" + fieldName + ",后台返回的类型为:" + jsonToken); + } + + @Override + public void onParseListException(TypeToken typeToken, String fieldName, JsonToken listItemJsonToken) { + handlerGsonParseException("解析 List 异常:" + typeToken + "#" + fieldName + ",后台返回的条目类型为:" + listItemJsonToken); + } + + @Override + public void onParseMapException(TypeToken typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) { + handlerGsonParseException("解析 Map 异常:" + typeToken + "#" + fieldName + ",mapItemKey = " + mapItemKey + ",后台返回的条目类型为:" + mapItemJsonToken); + } + + private void handlerGsonParseException(String message) { + if (BuildConfig.DEBUG) { + throw new IllegalArgumentException(message); + } else { + CrashReport.postCatchedException(new IllegalArgumentException(message)); + } + } + }); + // 网络请求框架初始化 IRequestServer server; if (BuildConfig.DEBUG) { diff --git a/app/src/main/java/com/hjq/easy/demo/BaseActivity.java b/app/src/main/java/com/hjq/easy/demo/BaseActivity.java index 29cd918..34f7e3e 100644 --- a/app/src/main/java/com/hjq/easy/demo/BaseActivity.java +++ b/app/src/main/java/com/hjq/easy/demo/BaseActivity.java @@ -1,12 +1,9 @@ package com.hjq.easy.demo; import android.app.ProgressDialog; - import androidx.appcompat.app.AppCompatActivity; - import com.hjq.http.listener.OnHttpListener; import com.hjq.toast.Toaster; - import okhttp3.Call; /** @@ -68,8 +65,8 @@ public void onHttpStart(Call call) { public void onHttpSuccess(Object result) {} @Override - public void onHttpFail(Exception e) { - Toaster.show(e.getMessage()); + public void onHttpFail(Throwable throwable) { + Toaster.show(throwable.getMessage()); } @Override diff --git a/app/src/main/java/com/hjq/easy/demo/MainActivity.java b/app/src/main/java/com/hjq/easy/demo/MainActivity.java index 051c386..81f1ed5 100644 --- a/app/src/main/java/com/hjq/easy/demo/MainActivity.java +++ b/app/src/main/java/com/hjq/easy/demo/MainActivity.java @@ -151,8 +151,8 @@ public void onHttpSuccess(HttpData result) { .setKeyword("搬砖不再有")) .execute(new ResponseClass>() {}); Toaster.show("同步请求成功,请看日志"); - } catch (Exception e) { - Toaster.show(e.getMessage()); + } catch (Throwable throwable) { + Toaster.show(throwable.getMessage()); } runOnUiThread(this::hideDialog); }).start(); @@ -219,7 +219,7 @@ public void onUpdateSuccess(Void result) { } @Override - public void onUpdateFail(Exception e) { + public void onUpdateFail(Throwable throwable) { Toaster.show("上传失败"); } @@ -282,9 +282,9 @@ public void onDownloadSuccess(File file) { } @Override - public void onDownloadFail(File file, Exception e) { - Toaster.show("下载失败:" + e.getMessage()); - if (e instanceof FileMd5Exception) { + public void onDownloadFail(File file, Throwable throwable) { + Toaster.show("下载失败:" + throwable.getMessage()); + if (throwable instanceof FileMd5Exception) { // 如果是文件 md5 校验失败,则删除文件 file.delete(); } diff --git a/app/src/main/java/com/hjq/easy/demo/http/model/RequestHandler.java b/app/src/main/java/com/hjq/easy/demo/http/model/RequestHandler.java index abe5b99..2d6f306 100644 --- a/app/src/main/java/com/hjq/easy/demo/http/model/RequestHandler.java +++ b/app/src/main/java/com/hjq/easy/demo/http/model/RequestHandler.java @@ -6,10 +6,8 @@ import android.graphics.BitmapFactory; import android.net.ConnectivityManager; import android.net.NetworkInfo; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.google.gson.JsonSyntaxException; import com.hjq.easy.demo.R; import com.hjq.easy.demo.http.exception.ResultException; @@ -27,14 +25,12 @@ import com.hjq.http.exception.ServerException; import com.hjq.http.exception.TimeoutException; import com.hjq.http.request.HttpRequest; - import java.io.IOException; import java.io.InputStream; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; import java.net.SocketTimeoutException; import java.net.UnknownHostException; - import okhttp3.Headers; import okhttp3.Response; import okhttp3.ResponseBody; @@ -55,8 +51,7 @@ public RequestHandler(Application application) { @NonNull @Override - public Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, - @NonNull Type type) throws Exception { + public Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Type type) throws Throwable { if (Response.class.equals(type)) { return response; } @@ -141,59 +136,59 @@ public Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Respo @NonNull @Override - public Exception requestFail(@NonNull HttpRequest httpRequest, @NonNull Exception e) { - if (e instanceof HttpException) { - if (e instanceof TokenException) { + public Throwable requestFail(@NonNull HttpRequest httpRequest, @NonNull Throwable throwable) { + if (throwable instanceof HttpException) { + if (throwable instanceof TokenException) { // 登录信息失效,跳转到登录页 } - return e; + return throwable; } - if (e instanceof SocketTimeoutException) { - return new TimeoutException(mApplication.getString(R.string.http_server_out_time), e); + if (throwable instanceof SocketTimeoutException) { + return new TimeoutException(mApplication.getString(R.string.http_server_out_time), throwable); } - if (e instanceof UnknownHostException) { + if (throwable instanceof UnknownHostException) { NetworkInfo info = ((ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); // 判断网络是否连接 if (info != null && info.isConnected()) { // 有连接就是服务器的问题 - return new ServerException(mApplication.getString(R.string.http_server_error), e); + return new ServerException(mApplication.getString(R.string.http_server_error), throwable); } // 没有连接就是网络异常 - return new NetworkException(mApplication.getString(R.string.http_network_error), e); + return new NetworkException(mApplication.getString(R.string.http_network_error), throwable); } - if (e instanceof IOException) { + if (throwable instanceof IOException) { // 出现该异常的两种情况 - // 1. 调用 EasyHttp.cancel + // 1. 调用 EasyHttp 取消请求 // 2. 网络请求被中断 - return new CancelException(mApplication.getString(R.string.http_request_cancel), e); + return new CancelException(mApplication.getString(R.string.http_request_cancel), throwable); } - return new HttpException(e.getMessage(), e); + return new HttpException(throwable.getMessage(), throwable); } @NonNull @Override - public Exception downloadFail(@NonNull HttpRequest httpRequest, @NonNull Exception e) { - if (e instanceof ResponseException) { - ResponseException responseException = ((ResponseException) e); + public Throwable downloadFail(@NonNull HttpRequest httpRequest, @NonNull Throwable throwable) { + if (throwable instanceof ResponseException) { + ResponseException responseException = ((ResponseException) throwable); Response response = responseException.getResponse(); responseException.setMessage(String.format(mApplication.getString(R.string.http_response_error), response.code(), response.message())); return responseException; - } else if (e instanceof NullBodyException) { - NullBodyException nullBodyException = ((NullBodyException) e); + } else if (throwable instanceof NullBodyException) { + NullBodyException nullBodyException = ((NullBodyException) throwable); nullBodyException.setMessage(mApplication.getString(R.string.http_response_null_body)); return nullBodyException; - } else if (e instanceof FileMd5Exception) { - FileMd5Exception fileMd5Exception = ((FileMd5Exception) e); + } else if (throwable instanceof FileMd5Exception) { + FileMd5Exception fileMd5Exception = ((FileMd5Exception) throwable); fileMd5Exception.setMessage(mApplication.getString(R.string.http_response_md5_error)); return fileMd5Exception; } - return requestFail(httpRequest, e); + return requestFail(httpRequest, throwable); } @Nullable diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index 9be597a..7ba2873 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -1,6 +1,16 @@ - + - + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 91c17e3..719ae42 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:4.1.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31' // OkHttp 抓包框架:https://github.com/lygttpod/AndroidMonitor // classpath 'io.github.lygttpod:monitor-plugin:0.0.1' } diff --git a/library/build.gradle b/library/build.gradle index c6193c8..e1f18d2 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,8 +5,8 @@ android { defaultConfig { minSdkVersion 16 - versionCode 1205 - versionName "12.5" + versionCode 1206 + versionName "12.6" } // 使用 JDK 1.8 diff --git a/library/src/main/java/com/hjq/http/EasyConfig.java b/library/src/main/java/com/hjq/http/EasyConfig.java index 0c2a70a..a8f85a9 100644 --- a/library/src/main/java/com/hjq/http/EasyConfig.java +++ b/library/src/main/java/com/hjq/http/EasyConfig.java @@ -10,6 +10,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; +import java.util.Map; import okhttp3.OkHttpClient; /** @@ -52,9 +53,9 @@ public static EasyConfig with(OkHttpClient client) { private OkHttpClient mClient; /** 通用参数 */ - private HashMap mParams; + private Map mParams; /** 通用请求头 */ - private HashMap mHeaders; + private Map mHeaders; /** 线程调度器 */ private ThreadSchedulers mThreadSchedulers = ThreadSchedulers.MAIN; @@ -102,17 +103,17 @@ public EasyConfig setClient(OkHttpClient client) { return this; } - public EasyConfig setParams(HashMap params) { + public EasyConfig setParams(Map params) { if (params == null) { - params = new HashMap<>(); + params = new HashMap<>(10); } mParams = params; return this; } - public EasyConfig setHeaders(HashMap headers) { + public EasyConfig setHeaders(Map headers) { if (headers == null) { - headers = new HashMap<>(); + headers = new HashMap<>(10); } mHeaders = headers; return this; @@ -204,11 +205,11 @@ public OkHttpClient getClient() { return mClient; } - public HashMap getParams() { + public Map getParams() { return mParams; } - public HashMap getHeaders() { + public Map getHeaders() { return mHeaders; } diff --git a/library/src/main/java/com/hjq/http/EasyHttp.java b/library/src/main/java/com/hjq/http/EasyHttp.java index 26e0cca..6b4d209 100644 --- a/library/src/main/java/com/hjq/http/EasyHttp.java +++ b/library/src/main/java/com/hjq/http/EasyHttp.java @@ -1,11 +1,9 @@ package com.hjq.http; import android.text.TextUtils; - import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.request.DeleteBodyRequest; -import com.hjq.http.request.DeleteRequest; +import com.hjq.http.request.DeleteUrlRequest; import com.hjq.http.request.DownloadRequest; import com.hjq.http.request.GetRequest; import com.hjq.http.request.HeadRequest; @@ -14,7 +12,6 @@ import com.hjq.http.request.PostRequest; import com.hjq.http.request.PutRequest; import com.hjq.http.request.TraceRequest; - import okhttp3.Call; import okhttp3.OkHttpClient; @@ -64,15 +61,27 @@ public static HeadRequest head(LifecycleOwner lifecycleOwner) { } /** - * Delete 请求 + * Delete 请求(默认使用 Url 传递参数) + * + * @param lifecycleOwner 请传入 AppCompatActivity 或者 AndroidX.Fragment 子类 + * 如需传入其他对象请参考以下两个类 + * {@link com.hjq.http.lifecycle.ActivityLifecycle} + * {@link com.hjq.http.lifecycle.ApplicationLifecycle} + */ + public static DeleteUrlRequest delete(LifecycleOwner lifecycleOwner) { + return deleteByUrl(lifecycleOwner); + } + + /** + * Delete 请求(参数使用 Url 传递) * * @param lifecycleOwner 请传入 AppCompatActivity 或者 AndroidX.Fragment 子类 * 如需传入其他对象请参考以下两个类 * {@link com.hjq.http.lifecycle.ActivityLifecycle} * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ - public static DeleteRequest delete(LifecycleOwner lifecycleOwner) { - return new DeleteRequest(lifecycleOwner); + public static DeleteUrlRequest deleteByUrl(LifecycleOwner lifecycleOwner) { + return new DeleteUrlRequest(lifecycleOwner); } /** @@ -83,7 +92,7 @@ public static DeleteRequest delete(LifecycleOwner lifecycleOwner) { * {@link com.hjq.http.lifecycle.ActivityLifecycle} * {@link com.hjq.http.lifecycle.ApplicationLifecycle} */ - public static DeleteBodyRequest deleteBody(LifecycleOwner lifecycleOwner) { + public static DeleteBodyRequest deleteByBody(LifecycleOwner lifecycleOwner) { return new DeleteBodyRequest(lifecycleOwner); } @@ -150,11 +159,11 @@ public static DownloadRequest download(LifecycleOwner lifecycleOwner) { /** * 根据 TAG 取消请求任务 */ - public static void cancel(Object tag) { - cancel(EasyUtils.getObjectTag(tag)); + public static void cancelByTag(Object tag) { + cancelByTag(EasyUtils.getObjectTag(tag)); } - public static void cancel(String tag) { + public static void cancelByTag(String tag) { if (tag == null) { return; } @@ -192,7 +201,7 @@ public static void cancel(String tag) { /** * 清除所有请求任务 */ - public static void cancel() { + public static void cancelAll() { OkHttpClient client = EasyConfig.getInstance().getClient(); // 清除排队等候的任务 diff --git a/library/src/main/java/com/hjq/http/EasyUtils.java b/library/src/main/java/com/hjq/http/EasyUtils.java index 85984ec..29e03cd 100644 --- a/library/src/main/java/com/hjq/http/EasyUtils.java +++ b/library/src/main/java/com/hjq/http/EasyUtils.java @@ -9,7 +9,7 @@ import androidx.annotation.Nullable; import com.hjq.http.annotation.HttpIgnore; import com.hjq.http.annotation.HttpRename; -import com.hjq.http.body.WrapperBody; +import com.hjq.http.body.WrapperRequestBody; import com.hjq.http.model.FileContentResolver; import com.hjq.http.model.ThreadSchedulers; import java.io.Closeable; @@ -140,8 +140,8 @@ public static void closeStream(Closeable closeable) { } try { closeable.close(); - } catch (Exception e) { - e.printStackTrace(); + } catch (Throwable throwable) { + throwable.printStackTrace(); } } @@ -617,8 +617,8 @@ public static List getAllFields(Class originalClass) { */ public static RequestBody findRealRequestBody(RequestBody body) { while (true) { - if (body instanceof WrapperBody) { - body = ((WrapperBody) body).getRequestBody(); + if (body instanceof WrapperRequestBody) { + body = ((WrapperRequestBody) body).getRequestBody(); } else { return body; } diff --git a/library/src/main/java/com/hjq/http/body/CustomTypeBody.java b/library/src/main/java/com/hjq/http/body/CustomTypeBody.java index 74ac62b..360ab5e 100644 --- a/library/src/main/java/com/hjq/http/body/CustomTypeBody.java +++ b/library/src/main/java/com/hjq/http/body/CustomTypeBody.java @@ -9,7 +9,7 @@ * time : 2022/09/17 * desc : 支持自定义 Content-Type 的 RequestBody */ -public class CustomTypeBody extends WrapperBody { +public class CustomTypeBody extends WrapperRequestBody { /** 内容类型 */ private MediaType mContentType; diff --git a/library/src/main/java/com/hjq/http/body/JsonBody.java b/library/src/main/java/com/hjq/http/body/JsonRequestBody.java similarity index 84% rename from library/src/main/java/com/hjq/http/body/JsonBody.java rename to library/src/main/java/com/hjq/http/body/JsonRequestBody.java index e2bc8a2..76ff442 100644 --- a/library/src/main/java/com/hjq/http/body/JsonBody.java +++ b/library/src/main/java/com/hjq/http/body/JsonRequestBody.java @@ -1,20 +1,16 @@ package com.hjq.http.body; import androidx.annotation.NonNull; - import com.hjq.http.EasyUtils; import com.hjq.http.model.ContentType; - -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; +import org.json.JSONArray; +import org.json.JSONObject; /** * author : Android 轮子哥 @@ -22,32 +18,32 @@ * time : 2019/12/28 * desc : Json 参数提交 */ -public class JsonBody extends RequestBody { +public class JsonRequestBody extends RequestBody { /** Json 数据 */ private final String mJson; /** 字节数组 */ private final byte[] mBytes; - public JsonBody(Map map) { + public JsonRequestBody(Map map) { this(new JSONObject(map)); } - public JsonBody(List list) { + public JsonRequestBody(List list) { this(new JSONArray(list)); } - public JsonBody(JSONObject jsonObject) { + public JsonRequestBody(JSONObject jsonObject) { mJson = EasyUtils.unescapeJson(jsonObject.toString()); mBytes = mJson.getBytes(); } - public JsonBody(JSONArray jsonArray) { + public JsonRequestBody(JSONArray jsonArray) { mJson = EasyUtils.unescapeJson(jsonArray.toString()); mBytes = mJson.getBytes(); } - public JsonBody(String json) { + public JsonRequestBody(String json) { mJson = json; mBytes = mJson.getBytes(); } diff --git a/library/src/main/java/com/hjq/http/body/ProgressBody.java b/library/src/main/java/com/hjq/http/body/ProgressMonitorRequestBody.java similarity index 69% rename from library/src/main/java/com/hjq/http/body/ProgressBody.java rename to library/src/main/java/com/hjq/http/body/ProgressMonitorRequestBody.java index 9bba426..85a63c1 100644 --- a/library/src/main/java/com/hjq/http/body/ProgressBody.java +++ b/library/src/main/java/com/hjq/http/body/ProgressMonitorRequestBody.java @@ -2,15 +2,12 @@ import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; import com.hjq.http.lifecycle.HttpLifecycleManager; import com.hjq.http.listener.OnUpdateListener; import com.hjq.http.request.HttpRequest; - import java.io.IOException; - import okhttp3.RequestBody; import okio.Buffer; import okio.BufferedSink; @@ -24,7 +21,7 @@ * time : 2020/08/15 * desc : RequestBody 包装类(用于获取上传进度) */ -public class ProgressBody extends WrapperBody { +public class ProgressMonitorRequestBody extends WrapperRequestBody { private final HttpRequest mHttpRequest; private final OnUpdateListener mListener; @@ -37,7 +34,7 @@ public class ProgressBody extends WrapperBody { /** 上传进度值 */ private int mUpdateProgress; - public ProgressBody(HttpRequest httpRequest, RequestBody body, LifecycleOwner lifecycleOwner, OnUpdateListener listener) { + public ProgressMonitorRequestBody(HttpRequest httpRequest, RequestBody body, LifecycleOwner lifecycleOwner, OnUpdateListener listener) { super(body); mHttpRequest = httpRequest; mLifecycleOwner = lifecycleOwner; @@ -63,24 +60,28 @@ public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); mUpdateByte += byteCount; - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), ProgressBody.this::callOnProgress); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), ProgressMonitorRequestBody.this::dispatchUpdateByteChangeCallback); } } - private void callOnProgress() { + private void dispatchUpdateByteChangeCallback() { if (mListener != null && HttpLifecycleManager.isLifecycleActive(mLifecycleOwner)) { mListener.onUpdateByteChange(mTotalByte, mUpdateByte); } - int progress = EasyUtils.getProgressProgress(mTotalByte, mUpdateByte); + + int currentProgress = EasyUtils.getProgressProgress(mTotalByte, mUpdateByte); // 只有上传进度发生改变的时候才回调此方法,避免引起不必要的 View 重绘 - if (progress != mUpdateProgress) { - mUpdateProgress = progress; - if (mListener != null && HttpLifecycleManager.isLifecycleActive(mLifecycleOwner)) { - mListener.onUpdateProgressChange(progress); - } - EasyLog.printLog(mHttpRequest, "Uploading in progress, uploaded: " + - mUpdateByte + " / " + mTotalByte + - ", progress: " + progress + "%"); + if (currentProgress == mUpdateProgress) { + return; } + + mUpdateProgress = currentProgress; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mLifecycleOwner)) { + mListener.onUpdateProgressChange(currentProgress); + } + + EasyLog.printLog(mHttpRequest, "Update progress change, uploaded: " + + mUpdateByte + " / " + mTotalByte + + ", progress: " + currentProgress + "%"); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/body/TextBody.java b/library/src/main/java/com/hjq/http/body/TextRequestBody.java similarity index 89% rename from library/src/main/java/com/hjq/http/body/TextBody.java rename to library/src/main/java/com/hjq/http/body/TextRequestBody.java index 5594a37..ad1f48d 100644 --- a/library/src/main/java/com/hjq/http/body/TextBody.java +++ b/library/src/main/java/com/hjq/http/body/TextRequestBody.java @@ -1,11 +1,8 @@ package com.hjq.http.body; import androidx.annotation.NonNull; - import com.hjq.http.model.ContentType; - import java.io.IOException; - import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; @@ -16,7 +13,7 @@ * time : 2020/10/26 * desc : 文本参数提交 */ -public class TextBody extends RequestBody { +public class TextRequestBody extends RequestBody { /** 字符串数据 */ private final String mText; @@ -24,11 +21,11 @@ public class TextBody extends RequestBody { /** 字节数组 */ private final byte[] mBytes; - public TextBody() { + public TextRequestBody() { this(""); } - public TextBody(String text) { + public TextRequestBody(String text) { mText = text; mBytes = mText.getBytes(); } diff --git a/library/src/main/java/com/hjq/http/body/UpdateBody.java b/library/src/main/java/com/hjq/http/body/UpdateStreamRequestBody.java similarity index 83% rename from library/src/main/java/com/hjq/http/body/UpdateBody.java rename to library/src/main/java/com/hjq/http/body/UpdateStreamRequestBody.java index 9cfe99c..e578056 100644 --- a/library/src/main/java/com/hjq/http/body/UpdateBody.java +++ b/library/src/main/java/com/hjq/http/body/UpdateStreamRequestBody.java @@ -2,12 +2,10 @@ import com.hjq.http.EasyUtils; import com.hjq.http.model.ContentType; - import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; - import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; @@ -20,7 +18,7 @@ * time : 2019/12/14 * desc : 上传文件流 */ -public class UpdateBody extends RequestBody { +public class UpdateStreamRequestBody extends RequestBody { /** 上传源 */ private final Source mSource; @@ -34,15 +32,15 @@ public class UpdateBody extends RequestBody { /** 内容大小 */ private final long mLength; - public UpdateBody(File file) throws FileNotFoundException { + public UpdateStreamRequestBody(File file) throws FileNotFoundException { this(Okio.source(file), ContentType.guessMimeType(file.getName()), file.getName(), file.length()); } - public UpdateBody(InputStream inputStream, String name) throws IOException { + public UpdateStreamRequestBody(InputStream inputStream, String name) throws IOException { this(Okio.source(inputStream), ContentType.STREAM, name, inputStream.available()); } - public UpdateBody(Source source, MediaType type, String name, long length) { + public UpdateStreamRequestBody(Source source, MediaType type, String name, long length) { mSource = source; mMediaType = type; mKeyName = name; diff --git a/library/src/main/java/com/hjq/http/body/WrapperBody.java b/library/src/main/java/com/hjq/http/body/WrapperRequestBody.java similarity index 89% rename from library/src/main/java/com/hjq/http/body/WrapperBody.java rename to library/src/main/java/com/hjq/http/body/WrapperRequestBody.java index 16001ec..fc68f44 100644 --- a/library/src/main/java/com/hjq/http/body/WrapperBody.java +++ b/library/src/main/java/com/hjq/http/body/WrapperRequestBody.java @@ -1,9 +1,7 @@ package com.hjq.http.body; import androidx.annotation.NonNull; - import java.io.IOException; - import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; @@ -14,11 +12,11 @@ * time : 2022/09/17 * desc : RequestBody 包装类 */ -public class WrapperBody extends RequestBody { +public class WrapperRequestBody extends RequestBody { private final RequestBody mRequestBody; - public WrapperBody(RequestBody body) { + public WrapperRequestBody(RequestBody body) { mRequestBody = body; } diff --git a/library/src/main/java/com/hjq/http/callback/BaseCallback.java b/library/src/main/java/com/hjq/http/callback/BaseCallback.java index a1a728d..2b13cd5 100644 --- a/library/src/main/java/com/hjq/http/callback/BaseCallback.java +++ b/library/src/main/java/com/hjq/http/callback/BaseCallback.java @@ -1,7 +1,6 @@ package com.hjq.http.callback; import androidx.annotation.NonNull; - import com.hjq.http.EasyConfig; import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; @@ -9,10 +8,8 @@ import com.hjq.http.model.CallProxy; import com.hjq.http.model.ThreadSchedulers; import com.hjq.http.request.HttpRequest; - import java.io.IOException; import java.net.SocketTimeoutException; - import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; @@ -59,10 +56,10 @@ protected CallProxy getCall() { public void onResponse(@NonNull Call call, @NonNull Response response) { try { // 收到响应 - onResponse(response); - } catch (Exception e) { + onHttpResponse(response); + } catch (Throwable throwable) { // 回调失败 - onFailure(e); + onHttpFailure(throwable); } finally { // 关闭响应 closeResponse(response); @@ -95,7 +92,7 @@ public void onFailure(@NonNull Call call, @NonNull IOException e) { return; } - onFailure(e); + onHttpFailure(e); } /** @@ -106,12 +103,12 @@ public void onFailure(@NonNull Call call, @NonNull IOException e) { /** * 请求成功 */ - protected abstract void onResponse(Response response) throws Exception; + protected abstract void onHttpResponse(Response response) throws Throwable; /** * 请求失败 */ - protected abstract void onFailure(Exception e); + protected abstract void onHttpFailure(Throwable e); /** * 关闭响应 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 feea0fa..e802ea7 100644 --- a/library/src/main/java/com/hjq/http/callback/DownloadCallback.java +++ b/library/src/main/java/com/hjq/http/callback/DownloadCallback.java @@ -1,9 +1,6 @@ package com.hjq.http.callback; -import android.text.TextUtils; - import androidx.annotation.NonNull; - import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; import com.hjq.http.config.IRequestInterceptor; @@ -13,11 +10,9 @@ import com.hjq.http.lifecycle.HttpLifecycleManager; import com.hjq.http.listener.OnDownloadListener; import com.hjq.http.request.HttpRequest; - import java.io.File; import java.io.InputStream; import java.io.OutputStream; - import okhttp3.Call; import okhttp3.Response; import okhttp3.ResponseBody; @@ -82,7 +77,7 @@ protected void onStart(Call call) { } @Override - protected void onResponse(Response response) throws Exception { + protected void onHttpResponse(Response response) throws Throwable { // 打印请求耗时时间 EasyLog.printLog(mHttpRequest, "RequestConsuming:" + (response.receivedResponseAtMillis() - response.sentRequestAtMillis()) + " ms"); @@ -122,7 +117,7 @@ protected void onResponse(Response response) throws Exception { } // 如果这个文件已经下载过,并且经过校验 MD5 是同一个文件的话,就直接回调下载成功监听 - if (!TextUtils.isEmpty(mMd5) && mFile.isFile() && + if (mFile.isFile() && mMd5 != null && !"".equals(mMd5) && mMd5.equalsIgnoreCase(EasyUtils.getFileMd5(EasyUtils.openFileInputStream(mFile)))) { // 文件已存在,跳过下载 EasyLog.printLog(mHttpRequest, mFile.getPath() + " file already exists, skip download"); @@ -138,74 +133,71 @@ protected void onResponse(Response response) throws Exception { while ((readLength = inputStream.read(bytes)) != -1) { mDownloadByte += readLength; outputStream.write(bytes, 0, readLength); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::dispatchDownloadProgressCallback); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::dispatchDownloadByteChangeCallback); } EasyUtils.closeStream(inputStream); EasyUtils.closeStream(outputStream); String md5 = EasyUtils.getFileMd5(EasyUtils.openFileInputStream(mFile)); - if (!TextUtils.isEmpty(mMd5) && !mMd5.equalsIgnoreCase(md5)) { + if (mMd5 != null && !"".equals(mMd5) && !mMd5.equalsIgnoreCase(md5)) { // 文件 MD5 值校验失败 - throw new FileMd5Exception("MD5 verify failure", md5); + throw new FileMd5Exception("File md5 hash verify failure", md5); } // 下载成功 mHttpRequest.getRequestHandler().downloadSuccess(mHttpRequest, response, mFile); - EasyLog.printLog(mHttpRequest, mFile.getPath() + " download completed"); EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchDownloadSuccessCallback(false)); } @Override - protected void onFailure(final Exception e) { - EasyLog.printThrowable(mHttpRequest, e); + protected void onHttpFailure(final Throwable throwable) { + EasyLog.printThrowable(mHttpRequest, throwable); // 打印错误堆栈 - final Exception finalException = mHttpRequest.getRequestHandler().downloadFail(mHttpRequest, e); - if (finalException != e) { - EasyLog.printThrowable(mHttpRequest, finalException); + final Throwable finalThrowable = mHttpRequest.getRequestHandler().downloadFail(mHttpRequest, throwable); + if (finalThrowable != throwable) { + EasyLog.printThrowable(mHttpRequest, finalThrowable); } - - EasyLog.printLog(mHttpRequest, mFile.getPath() + " download error"); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchDownloadFailCallback(finalException)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchDownloadFailCallback(finalThrowable)); } private void dispatchDownloadStartCallback() { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onDownloadStart(mFile); } - mListener.onDownloadStart(mFile); + EasyLog.printLog(mHttpRequest, "Download file start, file path = " + mFile.getPath()); } - private void dispatchDownloadProgressCallback() { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + private void dispatchDownloadByteChangeCallback() { + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onDownloadByteChange(mFile, mTotalByte, mDownloadByte); } - mListener.onDownloadByteChange(mFile, mTotalByte, mDownloadByte); - int progress = EasyUtils.getProgressProgress(mTotalByte, mDownloadByte); + int currentProgress = EasyUtils.getProgressProgress(mTotalByte, mDownloadByte); // 只有下载进度发生改变的时候才回调此方法,避免引起不必要的 View 重绘 - if (progress == mDownloadProgress) { + if (currentProgress == mDownloadProgress) { return; } - mDownloadProgress = progress; - mListener.onDownloadProgressChange(mFile, mDownloadProgress); - EasyLog.printLog(mHttpRequest, mFile.getPath() + - ", downloaded: " + mDownloadByte + " / " + mTotalByte + - ", progress: " + progress + " %"); + mDownloadProgress = currentProgress; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onDownloadProgressChange(mFile, mDownloadProgress); + } + EasyLog.printLog(mHttpRequest, "Download file progress change, downloaded: " + mDownloadByte + " / " + mTotalByte + + ", progress: " + currentProgress + " %" + "file path = " + mFile.getPath()); } private void dispatchDownloadSuccessCallback(boolean cache) { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onDownloadSuccess(mFile, cache); + mListener.onDownloadEnd(mFile); } - mListener.onDownloadSuccess(mFile, cache); - mListener.onDownloadEnd(mFile); + EasyLog.printLog(mHttpRequest, "Download file success, file path = " + mFile.getPath()); } - private void dispatchDownloadFailCallback(Exception e) { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + private void dispatchDownloadFailCallback(Throwable throwable) { + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onDownloadFail(mFile, throwable); + mListener.onDownloadEnd(mFile); } - mListener.onDownloadFail(mFile, e); - mListener.onDownloadEnd(mFile); + EasyLog.printLog(mHttpRequest, "Download file fail, file path = " + mFile.getPath()); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/callback/NormalCallback.java b/library/src/main/java/com/hjq/http/callback/NormalCallback.java index 5639f38..4d40cdd 100644 --- a/library/src/main/java/com/hjq/http/callback/NormalCallback.java +++ b/library/src/main/java/com/hjq/http/callback/NormalCallback.java @@ -1,7 +1,6 @@ package com.hjq.http.callback; import androidx.annotation.NonNull; - import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; import com.hjq.http.config.IRequestInterceptor; @@ -9,11 +8,9 @@ import com.hjq.http.listener.OnHttpListener; import com.hjq.http.model.CacheMode; import com.hjq.http.request.HttpRequest; - import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; - import okhttp3.Call; import okhttp3.Response; import okhttp3.ResponseBody; @@ -83,9 +80,9 @@ public void start() { }, 1); } - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(mHttpRequest, "ReadCache error"); - EasyLog.printThrowable(mHttpRequest, cacheException); + EasyLog.printThrowable(mHttpRequest, cacheThrowable); super.start(); } } @@ -96,7 +93,7 @@ protected void onStart(Call call) { } @Override - protected void onResponse(Response response) throws Exception { + protected void onHttpResponse(Response response) throws Throwable { // 打印请求耗时时间 EasyLog.printLog(mHttpRequest, "RequestConsuming:" + (response.receivedResponseAtMillis() - response.sentRequestAtMillis()) + " ms"); @@ -117,9 +114,9 @@ protected void onResponse(Response response) throws Exception { try { boolean writeCacheResult = mHttpRequest.getRequestHandler().writeCache(mHttpRequest, response, result); EasyLog.printLog(mHttpRequest, "write cache result:" + writeCacheResult); - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(mHttpRequest, "write cache error"); - EasyLog.printThrowable(mHttpRequest, cacheException); + EasyLog.printThrowable(mHttpRequest, cacheThrowable); } } @@ -127,11 +124,11 @@ protected void onResponse(Response response) throws Exception { } @Override - protected void onFailure(Exception exception) { + protected void onHttpFailure(Throwable throwable) { // 打印错误堆栈 - EasyLog.printThrowable(mHttpRequest, exception); + EasyLog.printThrowable(mHttpRequest, throwable); // 如果设置了只在网络请求失败才去读缓存 - if (exception instanceof IOException && mHttpRequest.getRequestCache().getCacheMode() == CacheMode.USE_CACHE_AFTER_FAILURE) { + if (throwable instanceof IOException && mHttpRequest.getRequestCache().getCacheMode() == CacheMode.USE_CACHE_AFTER_FAILURE) { try { Object result = mHttpRequest.getRequestHandler().readCache(mHttpRequest, mReflectType, mHttpRequest.getRequestCache().getCacheTime()); @@ -140,41 +137,41 @@ protected void onFailure(Exception exception) { EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpSuccessCallback(result, true)); return; } - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(mHttpRequest, "ReadCache error"); - EasyLog.printThrowable(mHttpRequest, cacheException); + EasyLog.printThrowable(mHttpRequest, cacheThrowable); } } - final Exception finalException = mHttpRequest.getRequestHandler().requestFail(mHttpRequest, exception); - if (finalException != exception) { - EasyLog.printThrowable(mHttpRequest, finalException); + final Throwable finalThrowable = mHttpRequest.getRequestHandler().requestFail(mHttpRequest, throwable); + if (finalThrowable != throwable) { + EasyLog.printThrowable(mHttpRequest, finalThrowable); } - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpFailCallback(finalException)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpFailCallback(finalThrowable)); } private void dispatchHttpStartCallback() { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onHttpStart(getCall()); } - mListener.onHttpStart(getCall()); + EasyLog.printLog(mHttpRequest, "Http request start"); } private void dispatchHttpSuccessCallback(Object result, boolean cache) { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onHttpSuccess(result, cache); + mListener.onHttpEnd(getCall()); } - mListener.onHttpSuccess(result, cache); - mListener.onHttpEnd(getCall()); + EasyLog.printLog(mHttpRequest, "Http request success"); } - private void dispatchHttpFailCallback(Exception e) { - if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { - return; + private void dispatchHttpFailCallback(Throwable throwable) { + if (mListener != null && HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { + mListener.onHttpFail(throwable); + mListener.onHttpEnd(getCall()); } - mListener.onHttpFail(e); - mListener.onHttpEnd(getCall()); + EasyLog.printLog(mHttpRequest, "Http request fail"); } @Override diff --git a/library/src/main/java/com/hjq/http/config/IRequestHandler.java b/library/src/main/java/com/hjq/http/config/IRequestHandler.java index 4386d8b..03e2433 100644 --- a/library/src/main/java/com/hjq/http/config/IRequestHandler.java +++ b/library/src/main/java/com/hjq/http/config/IRequestHandler.java @@ -2,13 +2,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.hjq.http.EasyUtils; import com.hjq.http.request.HttpRequest; - import java.io.File; import java.lang.reflect.Type; - import okhttp3.Response; /** @@ -27,10 +24,10 @@ public interface IRequestHandler { * @param type 解析类型 * @return 返回结果 * - * @throws Exception 如果抛出则回调失败 + * @throws Throwable 如果抛出则回调失败 */ @NonNull - Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Type type) throws Exception; + Object requestSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Type type) throws Throwable; /** * 请求失败 @@ -40,7 +37,7 @@ public interface IRequestHandler { * @return 错误对象 */ @NonNull - Exception requestFail(@NonNull HttpRequest httpRequest, @NonNull Exception e); + Throwable requestFail(@NonNull HttpRequest httpRequest, @NonNull Throwable e); /** * 下载开始 @@ -57,18 +54,18 @@ default void downloadStart(@NonNull HttpRequest httpRequest, @NonNull File fi * @param response 响应对象 * @param file 下载的文件对象 */ - default void downloadSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull File file) throws Exception {} + default void downloadSuccess(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull File file) throws Throwable {} /** * 下载失败 * * @param httpRequest 请求接口对象 - * @param e 错误对象 + * @param throwable 错误对象 * @return 错误对象 */ @NonNull - default Exception downloadFail(@NonNull HttpRequest httpRequest, @NonNull Exception e) { - return requestFail(httpRequest, e); + default Throwable downloadFail(@NonNull HttpRequest httpRequest, @NonNull Throwable throwable) { + return requestFail(httpRequest, throwable); } /** @@ -79,7 +76,7 @@ default Exception downloadFail(@NonNull HttpRequest httpRequest, @NonNull Exc * @return 返回新的请求对象 */ @Nullable - default Object readCache(@NonNull HttpRequest httpRequest, @NonNull Type type, long cacheTime) { + default Object readCache(@NonNull HttpRequest httpRequest, @NonNull Type type, long cacheTime) throws Throwable { return null; } @@ -90,7 +87,7 @@ default Object readCache(@NonNull HttpRequest httpRequest, @NonNull Type type * @param result 请求结果对象 * @return 缓存写入结果 */ - default boolean writeCache(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Object result) { + default boolean writeCache(@NonNull HttpRequest httpRequest, @NonNull Response response, @NonNull Object result) throws Throwable { return false; } diff --git a/library/src/main/java/com/hjq/http/config/impl/RequestFormBodyStrategy.java b/library/src/main/java/com/hjq/http/config/impl/RequestFormBodyStrategy.java index c8b71a0..382eb15 100644 --- a/library/src/main/java/com/hjq/http/config/impl/RequestFormBodyStrategy.java +++ b/library/src/main/java/com/hjq/http/config/impl/RequestFormBodyStrategy.java @@ -2,7 +2,7 @@ import android.text.TextUtils; import com.hjq.http.EasyLog; -import com.hjq.http.body.UpdateBody; +import com.hjq.http.body.UpdateStreamRequestBody; import com.hjq.http.config.IRequestBodyStrategy; import com.hjq.http.model.FileContentResolver; import com.hjq.http.model.HttpParams; @@ -130,11 +130,11 @@ private void addFormData(HttpRequest httpRequest, MultipartBody.Builder bodyB if (file instanceof FileContentResolver) { FileContentResolver fileContentResolver = (FileContentResolver) file; InputStream inputStream = fileContentResolver.openInputStream(); - part = MultipartBody.Part.createFormData(key, fileName, new UpdateBody( + part = MultipartBody.Part.createFormData(key, fileName, new UpdateStreamRequestBody( Okio.source(inputStream), fileContentResolver.getContentType(), fileName, inputStream.available())); } else { - part = MultipartBody.Part.createFormData(key, fileName, new UpdateBody(file)); + part = MultipartBody.Part.createFormData(key, fileName, new UpdateStreamRequestBody(file)); } bodyBuilder.addPart(part); } catch (FileNotFoundException e) { @@ -154,7 +154,7 @@ private void addFormData(HttpRequest httpRequest, MultipartBody.Builder bodyB // 如果这是一个 InputStream 对象 InputStream inputStream = (InputStream) object; try { - bodyBuilder.addPart(MultipartBody.Part.createFormData(key, null, new UpdateBody(inputStream, key))); + bodyBuilder.addPart(MultipartBody.Part.createFormData(key, null, new UpdateStreamRequestBody(inputStream, key))); } catch (IOException e) { EasyLog.printThrowable(httpRequest, e); } @@ -164,9 +164,9 @@ private void addFormData(HttpRequest httpRequest, MultipartBody.Builder bodyB if (object instanceof RequestBody) { // 如果这是一个自定义的 RequestBody 对象 RequestBody requestBody = (RequestBody) object; - if (requestBody instanceof UpdateBody) { + if (requestBody instanceof UpdateStreamRequestBody) { bodyBuilder.addPart(MultipartBody.Part.createFormData(key, - ((UpdateBody) requestBody).getKeyName(), requestBody)); + ((UpdateStreamRequestBody) requestBody).getKeyName(), requestBody)); } else { bodyBuilder.addPart(MultipartBody.Part.createFormData(key, null, requestBody)); } diff --git a/library/src/main/java/com/hjq/http/config/impl/RequestJsonBodyStrategy.java b/library/src/main/java/com/hjq/http/config/impl/RequestJsonBodyStrategy.java index 053d124..5cc0c00 100644 --- a/library/src/main/java/com/hjq/http/config/impl/RequestJsonBodyStrategy.java +++ b/library/src/main/java/com/hjq/http/config/impl/RequestJsonBodyStrategy.java @@ -1,7 +1,7 @@ package com.hjq.http.config.impl; import com.hjq.http.EasyUtils; -import com.hjq.http.body.JsonBody; +import com.hjq.http.body.JsonRequestBody; import com.hjq.http.config.IRequestBodyStrategy; import com.hjq.http.model.HttpParams; import com.hjq.http.request.HttpRequest; @@ -23,6 +23,6 @@ public void addParams(HttpParams params, String key, Object value) { @Override public RequestBody createRequestBody(HttpRequest httpRequest, HttpParams params) { - return new JsonBody(params.getParams()); + return new JsonRequestBody(params.getParams()); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java b/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java index 8a30a96..0812c03 100644 --- a/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java +++ b/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java @@ -4,7 +4,6 @@ import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleEventObserver; import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.EasyHttp; /** @@ -38,6 +37,6 @@ public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Ev // 移除监听 source.getLifecycle().removeObserver(this); // 取消请求 - EasyHttp.cancel(source); + EasyHttp.cancelByTag(source); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/listener/HttpCallbackProxy.java b/library/src/main/java/com/hjq/http/listener/HttpCallbackProxy.java index 3912c55..80d29bf 100644 --- a/library/src/main/java/com/hjq/http/listener/HttpCallbackProxy.java +++ b/library/src/main/java/com/hjq/http/listener/HttpCallbackProxy.java @@ -47,11 +47,11 @@ public void onHttpSuccess(T result) { } @Override - public void onHttpFail(Exception e) { + public void onHttpFail(Throwable throwable) { if (mSourceListener == null) { return; } - mSourceListener.onHttpFail(e); + mSourceListener.onHttpFail(throwable); } @Override 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 cfbd52b..3e36a88 100644 --- a/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java +++ b/library/src/main/java/com/hjq/http/listener/OnDownloadListener.java @@ -47,7 +47,7 @@ default void onDownloadSuccess(File file, boolean cache) { /** * 下载失败 */ - void onDownloadFail(File file, Exception e); + void onDownloadFail(File file, Throwable throwable); /** * 下载结束 diff --git a/library/src/main/java/com/hjq/http/listener/OnHttpListener.java b/library/src/main/java/com/hjq/http/listener/OnHttpListener.java index f6854d0..603bc41 100644 --- a/library/src/main/java/com/hjq/http/listener/OnHttpListener.java +++ b/library/src/main/java/com/hjq/http/listener/OnHttpListener.java @@ -32,7 +32,7 @@ default void onHttpSuccess(T result, boolean cache) { /** * 请求出错 */ - void onHttpFail(Exception e); + void onHttpFail(Throwable throwable); /** * 请求结束 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 5542905..3f094a1 100644 --- a/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java +++ b/library/src/main/java/com/hjq/http/listener/OnUpdateListener.java @@ -30,8 +30,8 @@ default void onHttpSuccess(T result) { * 请求出错 */ @Override - default void onHttpFail(Exception e) { - onUpdateFail(e); + default void onHttpFail(Throwable throwable) { + onUpdateFail(throwable); } /** @@ -72,7 +72,7 @@ default void onUpdateByteChange(long totalByte, long updateByte) {} /** * 上传出错 */ - void onUpdateFail(Exception e); + void onUpdateFail(Throwable throwable); /** * 上传结束 diff --git a/library/src/main/java/com/hjq/http/model/FileContentResolver.java b/library/src/main/java/com/hjq/http/model/FileContentResolver.java index b83e7e9..3c1c337 100644 --- a/library/src/main/java/com/hjq/http/model/FileContentResolver.java +++ b/library/src/main/java/com/hjq/http/model/FileContentResolver.java @@ -5,12 +5,9 @@ import android.database.Cursor; import android.net.Uri; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.hjq.http.EasyUtils; - import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; @@ -18,7 +15,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; - import okhttp3.MediaType; import okhttp3.RequestBody; @@ -51,7 +47,7 @@ public FileContentResolver(Context context, Uri uri, String fileName) { public FileContentResolver(ContentResolver resolver, Uri uri, String fileName) { super(new File(uri.toString()).getPath()); mContentResolver = resolver; - // 请注意这个 uri 是通过 ContentResolver.insert 方法生成的,并且没有经过修改的,否则会导致文件流读取失败 + // 请注意这个 uri 需要通过 ContentResolver.insert 方法生成的,并且没有经过修改的,否则会导致文件流读取失败 // 经过测试,ContentResolver.insert 生成的 uri 类型为 Uri.HierarchicalUri 这个内部类的 mContentUri = uri; if (!TextUtils.isEmpty(fileName)) { 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 17e628f..96ccf53 100644 --- a/library/src/main/java/com/hjq/http/model/HttpHeaders.java +++ b/library/src/main/java/com/hjq/http/model/HttpHeaders.java @@ -1,8 +1,8 @@ package com.hjq.http.model; import com.hjq.http.EasyConfig; - import java.util.HashMap; +import java.util.Map; import java.util.Set; /** @@ -14,7 +14,7 @@ public final class HttpHeaders { /** 请求头存放集合 */ - private final HashMap mHeaders = new HashMap<>(EasyConfig.getInstance().getHeaders()); + private final Map mHeaders = new HashMap<>(EasyConfig.getInstance().getHeaders()); public void put(String key, String value) { if (key == null || value == null) { @@ -46,7 +46,7 @@ public Set getKeys() { return mHeaders.keySet(); } - public HashMap getHeaders() { + public Map getHeaders() { return mHeaders; } } \ 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 4517497..03e6507 100644 --- a/library/src/main/java/com/hjq/http/model/HttpParams.java +++ b/library/src/main/java/com/hjq/http/model/HttpParams.java @@ -1,8 +1,8 @@ package com.hjq.http.model; import com.hjq.http.EasyConfig; - import java.util.HashMap; +import java.util.Map; import java.util.Set; /** @@ -14,7 +14,7 @@ public final class HttpParams { /** 请求参数存放集合 */ - private final HashMap mParams = new HashMap<>(EasyConfig.getInstance().getParams()); + private final Map mParams = new HashMap<>(EasyConfig.getInstance().getParams()); /** 是否有流参数 */ private boolean mMultipart; @@ -49,7 +49,7 @@ public Set getKeys() { return mParams.keySet(); } - public HashMap getParams() { + public Map getParams() { return mParams; } 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 4be00d4..c6703f4 100644 --- a/library/src/main/java/com/hjq/http/request/BodyRequest.java +++ b/library/src/main/java/com/hjq/http/request/BodyRequest.java @@ -6,9 +6,9 @@ import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; import com.hjq.http.body.CustomTypeBody; -import com.hjq.http.body.JsonBody; -import com.hjq.http.body.ProgressBody; -import com.hjq.http.body.TextBody; +import com.hjq.http.body.JsonRequestBody; +import com.hjq.http.body.ProgressMonitorRequestBody; +import com.hjq.http.body.TextRequestBody; import com.hjq.http.config.IRequestBodyStrategy; import com.hjq.http.listener.OnHttpListener; import com.hjq.http.listener.OnUpdateListener; @@ -46,21 +46,21 @@ public T json(Map map) { if (map == null) { return (T) this; } - return body(new JsonBody(map)); + return body(new JsonRequestBody(map)); } public T json(List list) { if (list == null) { return (T) this; } - return body(new JsonBody(list)); + return body(new JsonRequestBody(list)); } public T json(String json) { if (json == null) { return (T) this; } - return body(new JsonBody(json)); + return body(new JsonRequestBody(json)); } /** @@ -70,7 +70,7 @@ public T text(String text) { if (text == null) { return (T) this; } - return body(new TextBody(text)); + return body(new TextRequestBody(text)); } /** @@ -90,24 +90,27 @@ public void request(@Nullable OnHttpListener listener) { mUpdateListener = (OnUpdateListener) listener; } if (mRequestBody != null) { - mRequestBody = new ProgressBody(this, mRequestBody, getLifecycleOwner(), mUpdateListener); + mRequestBody = new ProgressMonitorRequestBody(this, mRequestBody, getLifecycleOwner(), mUpdateListener); } super.request(listener); } @Override - protected void addHttpParams(HttpParams params, String key, Object value, IRequestBodyStrategy requestBodyStrategy) { + protected void addHttpParams(HttpParams params, String key, Object value, + IRequestBodyStrategy requestBodyStrategy) { requestBodyStrategy.addParams(params, key, value); } @Override - protected void addRequestParams(Request.Builder requestBuilder, HttpParams params, @Nullable String contentType, IRequestBodyStrategy requestBodyStrategy) { + protected void addRequestParams(Request.Builder requestBuilder, HttpParams params, + @Nullable String contentType, IRequestBodyStrategy requestBodyStrategy) { RequestBody body = mRequestBody != null ? mRequestBody : createRequestBody(params, contentType, requestBodyStrategy); requestBuilder.method(getRequestMethod(), body); } @Override - protected void printRequestLog(Request request, HttpParams params, HttpHeaders headers, IRequestBodyStrategy requestBodyStrategy) { + protected void printRequestLog(Request request, HttpParams params, + HttpHeaders headers, IRequestBodyStrategy requestBodyStrategy) { if (!EasyConfig.getInstance().isLogEnabled()) { return; } @@ -162,10 +165,10 @@ protected void printRequestLog(Request request, HttpParams params, HttpHeaders h printKeyValue(key, value); } - } else if (body instanceof JsonBody) { + } else if (body instanceof JsonRequestBody) { // 打印 Json - EasyLog.printJson(this, String.valueOf(params)); - } else if (body instanceof TextBody) { + EasyLog.printJson(this, String.valueOf(body)); + } else if (body instanceof TextRequestBody) { // 打印文本 EasyLog.printLog(this, String.valueOf(body)); } else if (body != null) { @@ -180,7 +183,8 @@ protected void printRequestLog(Request request, HttpParams params, HttpHeaders h /** * 组装 RequestBody 对象 */ - private RequestBody createRequestBody(HttpParams params, @Nullable String contentType, IRequestBodyStrategy requestBodyStrategy) { + private RequestBody createRequestBody(HttpParams params, @Nullable String contentType, + IRequestBodyStrategy requestBodyStrategy) { RequestBody requestBody = requestBodyStrategy.createRequestBody(this, params); // 如果外层需要自定义 Content-Type 这个字段,那么就使用装饰设计模式,对原有的 RequestBody 对象进行扩展 @@ -195,7 +199,7 @@ private RequestBody createRequestBody(HttpParams params, @Nullable String conten // 如果当前设置了上传监听,那么就使用装饰设计模式,对原有的 RequestBody 对象进行扩展 if (mUpdateListener != null) { - requestBody = new ProgressBody(this, requestBody, getLifecycleOwner(), mUpdateListener); + requestBody = new ProgressMonitorRequestBody(this, requestBody, getLifecycleOwner(), mUpdateListener); } return requestBody; diff --git a/library/src/main/java/com/hjq/http/request/DeleteBodyRequest.java b/library/src/main/java/com/hjq/http/request/DeleteBodyRequest.java index cdda8b5..f6105e3 100644 --- a/library/src/main/java/com/hjq/http/request/DeleteBodyRequest.java +++ b/library/src/main/java/com/hjq/http/request/DeleteBodyRequest.java @@ -2,7 +2,6 @@ import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.model.HttpMethod; /** @@ -10,6 +9,8 @@ * github : https://github.com/getActivity/EasyHttp * time : 2020/10/07 * desc : Delete 请求(参数使用 Body 传递) + * doc : Delete 请求该用 Url 还是 Body 来传递参数: + * https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request */ public final class DeleteBodyRequest extends BodyRequest { diff --git a/library/src/main/java/com/hjq/http/request/DeleteRequest.java b/library/src/main/java/com/hjq/http/request/DeleteUrlRequest.java similarity index 75% rename from library/src/main/java/com/hjq/http/request/DeleteRequest.java rename to library/src/main/java/com/hjq/http/request/DeleteUrlRequest.java index bee56c8..6e28187 100644 --- a/library/src/main/java/com/hjq/http/request/DeleteRequest.java +++ b/library/src/main/java/com/hjq/http/request/DeleteUrlRequest.java @@ -2,20 +2,19 @@ import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.model.HttpMethod; /** * author : Android 轮子哥 * github : https://github.com/getActivity/EasyHttp * time : 2020/10/07 - * desc : Delete 请求 + * desc : Delete 请求(参数使用 Url 传递) * doc : Delete 请求该用 Url 还是 Body 来传递参数: * https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request */ -public final class DeleteRequest extends UrlRequest { +public final class DeleteUrlRequest extends UrlRequest { - public DeleteRequest(LifecycleOwner lifecycleOwner) { + public DeleteUrlRequest(LifecycleOwner lifecycleOwner) { super(lifecycleOwner); } diff --git a/library/src/main/java/com/hjq/http/request/HttpRequest.java b/library/src/main/java/com/hjq/http/request/HttpRequest.java index 98b6ff5..a991b50 100644 --- a/library/src/main/java/com/hjq/http/request/HttpRequest.java +++ b/library/src/main/java/com/hjq/http/request/HttpRequest.java @@ -3,7 +3,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LifecycleOwner; - import com.hjq.http.EasyConfig; import com.hjq.http.EasyHttp; import com.hjq.http.EasyLog; @@ -11,7 +10,6 @@ import com.hjq.http.annotation.HttpHeader; import com.hjq.http.annotation.HttpIgnore; import com.hjq.http.annotation.HttpRename; -import com.hjq.http.config.impl.RequestFormBodyStrategy; import com.hjq.http.callback.NormalCallback; import com.hjq.http.config.IRequestApi; import com.hjq.http.config.IRequestBodyStrategy; @@ -24,24 +22,23 @@ import com.hjq.http.config.IRequestType; import com.hjq.http.config.impl.EasyRequestApi; import com.hjq.http.config.impl.EasyRequestServer; +import com.hjq.http.config.impl.RequestFormBodyStrategy; import com.hjq.http.lifecycle.HttpLifecycleManager; import com.hjq.http.listener.OnHttpListener; -import com.hjq.http.model.RequestBodyType; import com.hjq.http.model.CacheMode; import com.hjq.http.model.CallProxy; import com.hjq.http.model.ContentType; import com.hjq.http.model.HttpHeaders; import com.hjq.http.model.HttpParams; +import com.hjq.http.model.RequestBodyType; import com.hjq.http.model.ResponseClass; import com.hjq.http.model.ThreadSchedulers; - import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; - import okhttp3.CacheControl; import okhttp3.Call; import okhttp3.Request; @@ -186,7 +183,7 @@ public T delay(long delayMillis) { } /** - * 设置请求的标记(可用于 {@link EasyHttp#cancel(String)}) + * 设置请求的标记(可用于 {@link EasyHttp#cancelByTag(String)}) */ public T tag(Object tag) { return tag(EasyUtils.getObjectTag(tag)); @@ -339,9 +336,9 @@ public void request(@Nullable OnHttpListener listener) { * 执行同步请求 * @param responseClass 需要解析泛型的对象 * @return 返回解析完成的对象 - * @throws Exception 如果请求失败或者解析失败则抛出异常 + * @throws Throwable 如果请求失败或者解析失败则抛出异常 */ - public Bean execute(ResponseClass responseClass) throws Exception { + public Bean execute(ResponseClass responseClass) throws Throwable { if (EasyUtils.isMainThread()) { // 同步请求是耗时操作,耗时操作不能在主线程中直接执行 throw new IllegalStateException("Synchronous requests are time-consuming operations, " + @@ -381,9 +378,9 @@ public Bean execute(ResponseClass responseClass) throws Exception { if (cacheResult != null) { return (Bean) cacheResult; } - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(this, "ReadCache error"); - EasyLog.printThrowable(this, cacheException); + EasyLog.printThrowable(this, cacheThrowable); } } @@ -395,37 +392,37 @@ public Bean execute(ResponseClass responseClass) throws Exception { try { boolean writeCacheResult = mRequestHandler.writeCache(this, response, result); EasyLog.printLog(this, "WriteCache result:" + writeCacheResult); - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(this, "WriteCache error"); - EasyLog.printThrowable(this, cacheException); + EasyLog.printThrowable(this, cacheThrowable); } } return (Bean) result; - } catch (Exception exception) { + } catch (Throwable throwable) { - EasyLog.printThrowable(this, exception); + EasyLog.printThrowable(this, throwable); // 如果设置了只在网络请求失败才去读缓存 - if (exception instanceof IOException && cacheMode == CacheMode.USE_CACHE_AFTER_FAILURE) { + if (throwable instanceof IOException && cacheMode == CacheMode.USE_CACHE_AFTER_FAILURE) { try { Object cacheResult = mRequestHandler.readCache(this, reflectType, mRequestCache.getCacheTime()); EasyLog.printLog(this, "ReadCache result:" + cacheResult); if (cacheResult != null) { return (Bean) cacheResult; } - } catch (Exception cacheException) { + } catch (Throwable cacheThrowable) { EasyLog.printLog(this, "ReadCache error"); - EasyLog.printThrowable(this, cacheException); + EasyLog.printThrowable(this, cacheThrowable); } } - Exception finalException = mRequestHandler.requestFail(this, exception); - if (finalException != exception) { - EasyLog.printThrowable(this, finalException); + Throwable finalThrowable = mRequestHandler.requestFail(this, throwable); + if (finalThrowable != throwable) { + EasyLog.printThrowable(this, finalThrowable); } - throw finalException; + throw finalThrowable; } } 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 70e2d67..5144459 100644 --- a/library/src/main/java/com/hjq/http/request/UrlRequest.java +++ b/library/src/main/java/com/hjq/http/request/UrlRequest.java @@ -31,7 +31,8 @@ protected void addHttpParams(HttpParams params, String key, Object value, IReque } @Override - protected void addRequestParams(Request.Builder requestBuilder, HttpParams params, @Nullable String contentType, IRequestBodyStrategy requestBodyStrategy) { + protected void addRequestParams(Request.Builder requestBuilder, HttpParams params, + @Nullable String contentType, IRequestBodyStrategy requestBodyStrategy) { HttpUrl.Builder urlBuilder = requestBuilder.build().url().newBuilder(); // 添加参数 if (!params.isEmpty()) { @@ -71,7 +72,8 @@ protected void addRequestParams(Request.Builder requestBuilder, HttpParams param } @Override - protected void printRequestLog(Request request, HttpParams params, HttpHeaders headers, IRequestBodyStrategy requestBodyStrategy) { + protected void printRequestLog(Request request, HttpParams params, HttpHeaders headers, + IRequestBodyStrategy requestBodyStrategy) { if (!EasyConfig.getInstance().isLogEnabled()) { return; } diff --git a/library/src/main/java/com/hjq/http/ssl/UnSafeHostnameVerifier.java b/library/src/main/java/com/hjq/http/ssl/UnSafeHostnameVerifier.java index e8aa347..358c002 100644 --- a/library/src/main/java/com/hjq/http/ssl/UnSafeHostnameVerifier.java +++ b/library/src/main/java/com/hjq/http/ssl/UnSafeHostnameVerifier.java @@ -1,7 +1,6 @@ package com.hjq.http.ssl; import android.annotation.SuppressLint; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; @@ -16,9 +15,9 @@ public final class UnSafeHostnameVerifier implements HostnameVerifier { @SuppressLint("BadHostnameVerifier") @Override public boolean verify(String hostname, SSLSession session) { - // 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配, - // 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。 - // 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true + // 此类是用于主机名验证的基接口,在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配, + // 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接,策略可以是基于证书的或依赖于其他验证方案。 + // 当验证 URL 主机名使用的默认规则失败时使用这些回调,如果主机名是可接受的,则返回 true return true; } } \ No newline at end of file