From 6420cfa1b1f99c1a21c851b4d7251e157a2b75d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Android=20=E8=BD=AE=E5=AD=90=E5=93=A5?= Date: Sun, 2 Apr 2023 10:24:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A1=86=E6=9E=B6=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=80=BB=E8=BE=91=20=E4=BC=98=E5=8C=96=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E6=96=B9=E6=B3=95=E5=92=8C=E7=B1=BB=E5=91=BD=E5=90=8D?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E5=BB=B6=E8=BF=9F=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=A2=AB=E5=8F=96=E6=B6=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E7=BB=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=8F=82=E6=95=B0=E6=97=A0=E6=B3=95=E8=A2=AB=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E8=A7=A3=E6=9E=90=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=A8=E5=A4=9A=E7=BA=BF=E7=A8=8B=E6=83=85?= =?UTF-8?q?=E5=86=B5=E4=B8=8B=E4=BD=BF=E7=94=A8=E5=BC=82=E6=AD=A5=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E4=BC=9A=E5=87=BA=E7=8E=B0=E7=B4=A2=E5=BC=95=E8=B6=8A?= =?UTF-8?q?=E7=95=8C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/issue_template_bug.md | 4 +- HelpDoc.md | 46 +++++++-------- README.md | 22 +++---- app/build.gradle | 8 +-- .../java/com/hjq/easy/demo/BaseActivity.java | 7 +-- .../java/com/hjq/easy/demo/MainActivity.java | 4 +- .../easy/demo/http/model/RequestHandler.java | 6 +- library/build.gradle | 4 +- .../src/main/java/com/hjq/http/EasyHttp.java | 26 +++++++-- .../src/main/java/com/hjq/http/EasyUtils.java | 57 ++++++++++++++++++- .../com/hjq/http/callback/BaseCallback.java | 7 ++- .../hjq/http/callback/DownloadCallback.java | 22 +++---- .../com/hjq/http/callback/NormalCallback.java | 20 +++---- .../com/hjq/http/config/IRequestHandler.java | 2 +- ...D5Exception.java => FileMd5Exception.java} | 12 ++-- .../hjq/http/lifecycle/ActivityLifecycle.java | 16 +++--- .../http/lifecycle/HttpLifecycleManager.java | 2 +- .../com/hjq/http/request/BodyRequest.java | 38 +++++++------ .../com/hjq/http/request/DownloadRequest.java | 2 +- .../com/hjq/http/request/HttpRequest.java | 6 +- 20 files changed, 197 insertions(+), 114 deletions(-) rename library/src/main/java/com/hjq/http/exception/{FileMD5Exception.java => FileMd5Exception.java} (50%) diff --git a/.github/ISSUE_TEMPLATE/issue_template_bug.md b/.github/ISSUE_TEMPLATE/issue_template_bug.md index dcace74..26ed3b7 100644 --- a/.github/ISSUE_TEMPLATE/issue_template_bug.md +++ b/.github/ISSUE_TEMPLATE/issue_template_bug.md @@ -16,7 +16,9 @@ assignees: getActivity * 复现步骤【必填】:XXX(注意:目前不受理没有复现步骤的 Bug 单) -* 是否必现【必填】:填是/否 +* 是否必现【必填】:是/否 + +* 项目 targetSdkVersion【必填】:XX * 出现问题的手机信息【必填】:请填写出现问题的品牌和机型 diff --git a/HelpDoc.md b/HelpDoc.md index a12092a..1f5a818 100644 --- a/HelpDoc.md +++ b/HelpDoc.md @@ -65,7 +65,7 @@ * [如何设置请求超时时间](#如何设置请求超时时间) * [如何设置不打印日志](#如何设置不打印日志) - + * [如何修改日志打印策略](#如何修改日志打印策略) * [如何取消已发起的请求](#如何取消已发起的请求) @@ -443,7 +443,7 @@ EasyHttp.post(this) @Override public void onSucceed(Xxx data) { - + } }); ``` @@ -481,7 +481,7 @@ public final class RequestHandler implements IRequestHandler { mApplication = application; mMmkv = MMKV.mmkvWithID("http_cache_id"); } - + .................. @Nullable @@ -717,7 +717,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + @HttpIgnore private String token; } @@ -980,7 +980,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + @HttpIgnore private String address; } @@ -996,7 +996,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + @HttpHeader private String time; } @@ -1012,7 +1012,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + @HttpRename("k") private String keyword; } @@ -1024,13 +1024,13 @@ public final class XxxApi implements IRequestApi { ```java public final class XxxApi implements IRequestApi { - + @NonNull @Override public String getApi() { return "xxx/xxxx"; } - + private File file; } ``` @@ -1039,13 +1039,13 @@ public final class XxxApi implements IRequestApi { ```java public final class XxxApi implements IRequestApi { - + @NonNull @Override public String getApi() { return "xxx/xxxx"; } - + private InputStream inputStream; } ``` @@ -1060,7 +1060,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + private RequestBody requestBody; } ``` @@ -1075,7 +1075,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxxx"; } - + private List files; } ``` @@ -1147,7 +1147,7 @@ EasyConfig.with(okHttpClient) * 需要修改日志打印策略的场景 * 需要将请求的日志写入到本地 - + * 需要修改打印的请求日志格式 #### 如何取消已发起的请求 @@ -1172,7 +1172,7 @@ EasyHttp.post(MainActivity.this) @Override public void onSucceed(HttpData result) { - + } }); ``` @@ -1207,7 +1207,7 @@ EasyHttp.post(this) @Override public void onSucceed(Xxx result) { - + } }); ``` @@ -1394,7 +1394,7 @@ EasyHttp.post(this) @Override public void onSucceed(Xxx result) { - + } @Override @@ -1493,7 +1493,7 @@ EasyHttp.post(this) @Override public void onSucceed(HttpData result) { - + } }); ``` @@ -1590,7 +1590,7 @@ EasyHttp.get(this) @Override public void onSucceed(Xxx result) { - + } }); ``` @@ -1620,7 +1620,7 @@ Observable.create(new ObservableOnSubscribe>() { @Override public void subscribe(ObservableEmitter> emitter) throws Exception { - + HttpData data1; try { data1 = EasyHttp.post(MainActivity.this) @@ -1657,7 +1657,7 @@ Observable.create(new ObservableOnSubscribe>() { } }, new Consumer() { - + @Override public void accept(Throwable throwable) throws Exception { toast(throwable.getMessage()); @@ -1738,9 +1738,9 @@ Observable.create(new ObservableOnSubscribe>() { public void accept(String s) throws Exception { Log.i("EasyHttp", ""当前页码位置" + s); } - + }, new Consumer() { - + @Override public void accept(Throwable throwable) throws Exception { toast(throwable.getMessage()); diff --git a/README.md b/README.md index 0ea2d29..60fd3c8 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/11.6/EasyHttp.apk) +* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处下载Demo](https://github.com/getActivity/EasyHttp/releases/download/11.8/EasyHttp.apk) ![](picture/demo_code.png) @@ -61,7 +61,7 @@ android { dependencies { // 网络请求框架:https://github.com/getActivity/EasyHttp - implementation 'com.github.getActivity:EasyHttp:11.6' + implementation 'com.github.getActivity:EasyHttp:11.8' // OkHttp 框架:https://github.com/square/okhttp // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.13' @@ -69,16 +69,16 @@ dependencies { ``` * 需要注意的是:由于使用了 Lifecycle 特性,目前框架只支持 AndroidX 的项目集成 - + ## [框架的具体用法请点击这里查看](HelpDoc.md) ### 不同网络请求框架之间的对比 | 功能或细节 | [EasyHttp](https://github.com/getActivity/EasyHttp) | [Retrofit](https://github.com/square/retrofit) | [OkGo](https://github.com/jeasonlzy/okhttp-OkGo) | | :----: | :------: | :-----: | :-----: | -| 对应版本 | 11.6 | 2.9.0 | 3.0.4 | +| 对应版本 | 11.8 | 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 包大小** | 89 KB | 123 KB | 131 KB | +| **aar 包大小** | 90 KB | 123 KB | 131 KB | | minSdk 要求 | API 14+ | API 21+ | API 14+ | | 配置多域名 | ✅ | ❌ | ✅ | | **动态 Host** | ✅ | ❌ | ❌ | @@ -109,9 +109,9 @@ dependencies { * OkGo 其实也存在一些弊端,例如会把参数的 key 引用放到外层去,这样会引发一些问题: 1. Key 管理问题:这个 key 可能会在外层被使用很多次,这样参数的 key 管理就会变得不可控,后续接口改动可能会出现漏改的风险,尽管这种情况比较少见,但是也不容忽视,而 EasyHttp 没有这个问题,因为 EasyHttp 不会将参数 key 值放置到外层中去。 - + 2. 接口参数注释的问题:站在代码的规范角度上讲,我们应该在代码中注明参数的含义及作用,如果一旦将 key 放到外层,那么每一处调用的地方都需要写一遍注释,而 EasyHttp 是将参数字段化,只需要写一次注释到字段上即可。 - + 3. 接口信息完整信息展示:使用 OkGo 请求网络,只能在调用的地方看到传递的接口参数,而一些被其他地方引用的参数,我们无法很直观的看到,只能通过追踪代码或者查看文档来得知,而 EasyHttp 将一个接口的信息全部通过一个类来管理的,这个类其实就相当于一个接口文档。 4. 接口的动态化配置:除了接口的参数之外,一个接口还有可能单独配置 OkHttpClient 对象、参数的提交方式、接口响应处理方式等,这些用 OkGo 是可以实现,但是每个地方都要写一次,而 EasyHttp 可以直接在 API 类中配置,真正做到一劳永逸。 @@ -127,7 +127,7 @@ public final class XxxApi implements IRequestApi { public String getApi() { return "xxx/xxx"; } - + private int xxx; public XxxApi setXxx(int xxx) { @@ -166,7 +166,7 @@ public final class HttpLifecycleManager implements LifecycleEventObserver { /** * 绑定组件的生命周期 */ - public static void bind(LifecycleOwner lifecycleOwner) { + public static void register(LifecycleOwner lifecycleOwner) { lifecycleOwner.getLifecycle().addObserver(new HttpLifecycleManager()); } @@ -208,7 +208,7 @@ EasyHttp.post(this) @Override public void onSucceed(HttpData result) { - + } }); ``` @@ -249,6 +249,8 @@ EasyHttp.post(this) * 表情包大集合:[EmojiPackage](https://github.com/getActivity/EmojiPackage) ![](https://img.shields.io/github/stars/getActivity/EmojiPackage.svg) ![](https://img.shields.io/github/forks/getActivity/EmojiPackage.svg) +* AI 资源大汇总:[AiIndex](https://github.com/getActivity/AiIndex) ![](https://img.shields.io/github/stars/getActivity/AiIndex.svg) ![](https://img.shields.io/github/forks/getActivity/AiIndex.svg) + * 省市区 Json 数据:[ProvinceJson](https://github.com/getActivity/ProvinceJson) ![](https://img.shields.io/github/stars/getActivity/ProvinceJson.svg) ![](https://img.shields.io/github/forks/getActivity/ProvinceJson.svg) * Markdown 语法文档:[MarkdownDoc](https://github.com/getActivity/MarkdownDoc) ![](https://img.shields.io/github/stars/getActivity/MarkdownDoc.svg) ![](https://img.shields.io/github/forks/getActivity/MarkdownDoc.svg) diff --git a/app/build.gradle b/app/build.gradle index 6a47839..399d63b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId 'com.hjq.easy.demo' minSdkVersion 21 targetSdkVersion 31 - versionCode 1160 - versionName '11.6' + versionCode 1180 + versionName '11.8' } // 支持 JDK 1.8 @@ -76,10 +76,10 @@ dependencies { implementation 'com.github.getActivity:Toaster:12.0' // 权限请求框架:https://github.com/getActivity/XXPermissions - implementation 'com.github.getActivity:XXPermissions:16.6' + implementation 'com.github.getActivity:XXPermissions:16.8' // 标题栏框架:https://github.com/getActivity/TitleBar - implementation 'com.github.getActivity:TitleBar:10.0' + implementation 'com.github.getActivity:TitleBar:10.2' // Json 解析框架:https://github.com/google/gson implementation 'com.google.code.gson:gson:2.10.1' 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 ee93f2b..07145f2 100644 --- a/app/src/main/java/com/hjq/easy/demo/BaseActivity.java +++ b/app/src/main/java/com/hjq/easy/demo/BaseActivity.java @@ -4,7 +4,6 @@ import androidx.appcompat.app.AppCompatActivity; -import com.hjq.easy.demo.http.model.HttpData; import com.hjq.http.listener.OnHttpListener; import com.hjq.toast.Toaster; @@ -66,11 +65,7 @@ public void onStart(Call call) { } @Override - public void onSucceed(Object result) { - if (result instanceof HttpData) { - Toaster.show(((HttpData) result).getMessage()); - } - } + public void onSucceed(Object result) {} @Override public void onFail(Exception e) { 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 205a63d..6e5e1c1 100644 --- a/app/src/main/java/com/hjq/easy/demo/MainActivity.java +++ b/app/src/main/java/com/hjq/easy/demo/MainActivity.java @@ -25,7 +25,7 @@ import com.hjq.easy.demo.http.model.HttpData; import com.hjq.http.EasyHttp; import com.hjq.http.EasyUtils; -import com.hjq.http.exception.FileMD5Exception; +import com.hjq.http.exception.FileMd5Exception; import com.hjq.http.listener.HttpCallback; import com.hjq.http.listener.OnDownloadListener; import com.hjq.http.listener.OnUpdateListener; @@ -288,7 +288,7 @@ public void onComplete(File file) { @Override public void onError(File file, Exception e) { Toaster.show(e.getMessage()); - if (e instanceof FileMD5Exception) { + if (e 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 fd91891..aec862c 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 @@ -19,7 +19,7 @@ import com.hjq.http.config.IRequestHandler; import com.hjq.http.exception.CancelException; import com.hjq.http.exception.DataException; -import com.hjq.http.exception.FileMD5Exception; +import com.hjq.http.exception.FileMd5Exception; import com.hjq.http.exception.HttpException; import com.hjq.http.exception.NetworkException; import com.hjq.http.exception.NullBodyException; @@ -188,8 +188,8 @@ public Exception downloadFail(@NonNull HttpRequest httpRequest, @NonNull Exce NullBodyException nullBodyException = ((NullBodyException) e); nullBodyException.setMessage(mApplication.getString(R.string.http_response_null_body)); return nullBodyException; - } else if (e instanceof FileMD5Exception) { - FileMD5Exception fileMd5Exception = ((FileMD5Exception) e); + } else if (e instanceof FileMd5Exception) { + FileMd5Exception fileMd5Exception = ((FileMd5Exception) e); fileMd5Exception.setMessage(mApplication.getString(R.string.http_response_md5_error)); return fileMd5Exception; } diff --git a/library/build.gradle b/library/build.gradle index c472099..d2d6fc1 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,8 +5,8 @@ android { defaultConfig { minSdkVersion 14 - versionCode 1160 - versionName "11.6" + versionCode 1180 + versionName "11.8" } // 使用 JDK 1.8 diff --git a/library/src/main/java/com/hjq/http/EasyHttp.java b/library/src/main/java/com/hjq/http/EasyHttp.java index a483b62..26e0cca 100644 --- a/library/src/main/java/com/hjq/http/EasyHttp.java +++ b/library/src/main/java/com/hjq/http/EasyHttp.java @@ -1,5 +1,7 @@ package com.hjq.http; +import android.text.TextUtils; + import androidx.lifecycle.LifecycleOwner; import com.hjq.http.request.DeleteBodyRequest; @@ -161,17 +163,30 @@ public static void cancel(String tag) { // 清除排队等候的任务 for (Call call : client.dispatcher().queuedCalls()) { - if (tag.equals(call.request().tag())) { - call.cancel(); + Object requestTag = call.request().tag(); + if (requestTag == null) { + continue; + } + if (!TextUtils.equals(tag, String.valueOf(requestTag))) { + continue; } + call.cancel(); } // 清除正在执行的任务 for (Call call : client.dispatcher().runningCalls()) { - if (tag.equals(call.request().tag())) { - call.cancel(); + Object requestTag = call.request().tag(); + if (requestTag == null) { + continue; + } + if (!TextUtils.equals(tag, String.valueOf(requestTag))) { + continue; } + call.cancel(); } + + // 移除延迟发起的网络请求 + EasyUtils.removeDelayedRunnable(tag.hashCode()); } /** @@ -189,5 +204,8 @@ public static void cancel() { for (Call call : client.dispatcher().runningCalls()) { call.cancel(); } + + // 移除延迟发起的网络请求 + EasyUtils.removeAllRunnable(); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/EasyUtils.java b/library/src/main/java/com/hjq/http/EasyUtils.java index 61f1be2..e53ad55 100644 --- a/library/src/main/java/com/hjq/http/EasyUtils.java +++ b/library/src/main/java/com/hjq/http/EasyUtils.java @@ -2,6 +2,7 @@ import android.os.Handler; import android.os.Looper; +import android.os.Message; import android.text.TextUtils; import android.util.LruCache; @@ -27,6 +28,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; @@ -98,12 +100,35 @@ public static void runOnAssignThread(ThreadSchedulers schedulers, Runnable runna } /** - * 延迟一段时间执行 + * 延迟一段时间执行任务 */ - public static void postDelayed(Runnable runnable, long delayMillis) { + public static void postDelayedRunnable(Runnable runnable, long delayMillis) { HANDLER.postDelayed(runnable, delayMillis); } + /** + * 延迟一段时间执行任务(带一定的标识,方便后续移除) + */ + public static void postDelayedRunnable(Runnable runnable, int what, long delayMillis) { + Message msg = Message.obtain(HANDLER, runnable); + msg.what = what; + HANDLER.sendMessageDelayed(msg, delayMillis); + } + + /** + * 移除指定的消息 + */ + public static void removeDelayedRunnable(int what) { + HANDLER.removeMessages(what); + } + + /** + * 移除所有消息 + */ + public static void removeAllRunnable() { + HANDLER.removeCallbacksAndMessages(null); + } + /** * 判断当前是否为主线程 */ @@ -125,6 +150,13 @@ public static void closeStream(Closeable closeable) { } } + /** + * 判断对象是否为数组类型 + */ + public static boolean isArrayType(Object object) { + return object.getClass().isArray(); + } + /** * 判断对象是否为 Bean 类 */ @@ -135,6 +167,9 @@ public static boolean isBeanType(Object object) { if (object instanceof Enum) { return false; } + if (isArrayType(object)) { + return false; + } // Number:Long、Integer、Short、Double、Float、Byte // CharSequence:String、StringBuilder、StringBuilder return !(object instanceof Number || object instanceof CharSequence || object instanceof Boolean || @@ -237,6 +272,8 @@ public static boolean isMultipartClass(Type type) { /** * 将 List 集合转 JsonArray 对象 + * + * Github issue 地址:https://github.com/getActivity/EasyHttp/issues/164 */ public static JSONArray listToJsonArray(List list) { JSONArray jsonArray = new JSONArray(); @@ -277,6 +314,19 @@ public static JSONObject mapToJsonObject(Map map) { return jsonObject; } + /** + * 将数组转换成 List 集合 + */ + public static List arrayToList(Object array) { + List list = new ArrayList<>(); + int length = Array.getLength(array); + for (int i = 0; i < length; i++) { + Object element = Array.get(array, i); + list.add(element); + } + return list; + } + /** * 将 Bean 类转成 HashMap 对象 */ @@ -345,6 +395,9 @@ public static Object convertObject(Object object) { } else if (object instanceof Enum) { // 如果这是一个枚举的参数 return String.valueOf(object); + } else if (isArrayType(object)) { + // 如果这是一个数组参数,需要放在判断 Bean 类前面 + return listToJsonArray(arrayToList(object)); } else if (isBeanType(object)) { // 如果这是一个 Bean 参数 return mapToJsonObject(beanToHashMap(object)); 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 582f3ec..0b11f2b 100644 --- a/library/src/main/java/com/hjq/http/callback/BaseCallback.java +++ b/library/src/main/java/com/hjq/http/callback/BaseCallback.java @@ -7,6 +7,7 @@ import com.hjq.http.EasyUtils; import com.hjq.http.lifecycle.HttpLifecycleManager; import com.hjq.http.model.CallProxy; +import com.hjq.http.model.ThreadSchedulers; import com.hjq.http.request.HttpRequest; import java.io.IOException; @@ -35,7 +36,9 @@ public abstract class BaseCallback implements Callback { public BaseCallback(@NonNull HttpRequest request) { mHttpRequest = request; - HttpLifecycleManager.bind(mHttpRequest.getLifecycleOwner()); + // Lifecycle addObserver 需要在主线程中执行,所以这里要做一下线程转换 + EasyUtils.runOnAssignThread(ThreadSchedulers.MainThread, + () -> HttpLifecycleManager.register(mHttpRequest.getLifecycleOwner())); } public BaseCallback setCall(CallProxy call) { @@ -71,7 +74,7 @@ public void onFailure(@NonNull Call call, @NonNull IOException e) { // 服务器请求超时重试 if (e instanceof SocketTimeoutException && mRetryCount < EasyConfig.getInstance().getRetryCount()) { // 设置延迟 N 秒后重试该请求 - EasyUtils.postDelayed(() -> { + EasyUtils.postDelayedRunnable(() -> { // 前提是宿主还没有被销毁 if (!HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { 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 b8972a6..ff8e811 100644 --- a/library/src/main/java/com/hjq/http/callback/DownloadCallback.java +++ b/library/src/main/java/com/hjq/http/callback/DownloadCallback.java @@ -7,7 +7,7 @@ import com.hjq.http.EasyLog; import com.hjq.http.EasyUtils; import com.hjq.http.config.IRequestInterceptor; -import com.hjq.http.exception.FileMD5Exception; +import com.hjq.http.exception.FileMd5Exception; import com.hjq.http.exception.NullBodyException; import com.hjq.http.exception.ResponseException; import com.hjq.http.lifecycle.HttpLifecycleManager; @@ -78,7 +78,7 @@ public DownloadCallback setListener(OnDownloadListener listener) { @Override protected void onStart(Call call) { mHttpRequest.getRequestHandler().downloadStart(mHttpRequest, mFile); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::callOnStart); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::dispatchDownloadStartCallback); } @Override @@ -126,7 +126,7 @@ protected void onResponse(Response response) throws Exception { mMd5.equalsIgnoreCase(EasyUtils.getFileMd5(EasyUtils.openFileInputStream(mFile)))) { // 文件已存在,跳过下载 EasyLog.printLog(mHttpRequest, mFile.getPath() + " file already exists, skip download"); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnComplete(true)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchDownloadCompleteCallback(true)); return; } @@ -138,7 +138,7 @@ 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::callOnProgress); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::dispatchDownloadProgressCallback); } EasyUtils.closeStream(inputStream); EasyUtils.closeStream(outputStream); @@ -146,14 +146,14 @@ protected void onResponse(Response response) throws Exception { String md5 = EasyUtils.getFileMd5(EasyUtils.openFileInputStream(mFile)); if (!TextUtils.isEmpty(mMd5) && !mMd5.equalsIgnoreCase(md5)) { // 文件 MD5 值校验失败 - throw new FileMD5Exception("MD5 verify failure", md5); + throw new FileMd5Exception("MD5 verify failure", md5); } // 下载成功 mHttpRequest.getRequestHandler().downloadSucceed(mHttpRequest, response, mFile); EasyLog.printLog(mHttpRequest, mFile.getPath() + " download completed"); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnComplete(false)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchDownloadCompleteCallback(false)); } @Override @@ -166,17 +166,17 @@ protected void onFailure(final Exception e) { } EasyLog.printLog(mHttpRequest, mFile.getPath() + " download error"); - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnError(finalException)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callDownloadError(finalException)); } - private void callOnStart() { + private void dispatchDownloadStartCallback() { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } mListener.onStart(mFile); } - private void callOnProgress() { + private void dispatchDownloadProgressCallback() { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } @@ -193,7 +193,7 @@ private void callOnProgress() { ", progress: " + progress + " %"); } - private void callOnComplete(boolean cache) { + private void dispatchDownloadCompleteCallback(boolean cache) { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } @@ -201,7 +201,7 @@ private void callOnComplete(boolean cache) { mListener.onEnd(mFile); } - private void callOnError(Exception e) { + private void callDownloadError(Exception e) { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } 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 8dc862d..b7c2d44 100644 --- a/library/src/main/java/com/hjq/http/callback/NormalCallback.java +++ b/library/src/main/java/com/hjq/http/callback/NormalCallback.java @@ -41,7 +41,7 @@ public NormalCallback(@NonNull HttpRequest request) { public NormalCallback setListener(OnHttpListener listener) { mListener = listener; - mReflectType = mHttpRequest.getRequestHandler().getType(mListener); + mReflectType = mHttpRequest.getRequestHandler().getGenericType(mListener); return this; } @@ -68,12 +68,12 @@ public void start() { // 读取缓存成功 EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> { onStart(getCall()); - callOnSucceed(result, true); + dispatchHttpSucceedCallback(result, true); }); // 如果当前模式是先读缓存再写请求 if (cacheMode == CacheMode.USE_CACHE_FIRST) { - EasyUtils.postDelayed(() -> { + EasyUtils.postDelayedRunnable(() -> { if (!HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } @@ -92,7 +92,7 @@ public void start() { @Override protected void onStart(Call call) { - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::callOnStart); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), this::dispatchHttpStartCallback); } @Override @@ -123,7 +123,7 @@ protected void onResponse(Response response) throws Exception { } } - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnSucceed(result, false)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpSucceedCallback(result, false)); } @Override @@ -137,7 +137,7 @@ protected void onFailure(Exception exception) { mReflectType, mHttpRequest.getRequestCache().getCacheTime()); EasyLog.printLog(mHttpRequest, "ReadCache result:" + result); if (result != null) { - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnSucceed(result, true)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpSucceedCallback(result, true)); return; } } catch (Exception cacheException) { @@ -151,17 +151,17 @@ protected void onFailure(Exception exception) { EasyLog.printThrowable(mHttpRequest, finalException); } - EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> callOnFail(finalException)); + EasyUtils.runOnAssignThread(mHttpRequest.getThreadSchedulers(), () -> dispatchHttpFailCallback(finalException)); } - private void callOnStart() { + private void dispatchHttpStartCallback() { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } mListener.onStart(getCall()); } - private void callOnSucceed(Object result, boolean cache) { + private void dispatchHttpSucceedCallback(Object result, boolean cache) { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } @@ -169,7 +169,7 @@ private void callOnSucceed(Object result, boolean cache) { mListener.onEnd(getCall()); } - private void callOnFail(Exception e) { + private void dispatchHttpFailCallback(Exception e) { if (mListener == null || !HttpLifecycleManager.isLifecycleActive(mHttpRequest.getLifecycleOwner())) { return; } 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 2989a6a..c11878c 100644 --- a/library/src/main/java/com/hjq/http/config/IRequestHandler.java +++ b/library/src/main/java/com/hjq/http/config/IRequestHandler.java @@ -102,7 +102,7 @@ default void clearCache() {} /** * 解析泛型 */ - default Type getType(Object object) { + default Type getGenericType(Object object) { return EasyUtils.getGenericType(object); } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/exception/FileMD5Exception.java b/library/src/main/java/com/hjq/http/exception/FileMd5Exception.java similarity index 50% rename from library/src/main/java/com/hjq/http/exception/FileMD5Exception.java rename to library/src/main/java/com/hjq/http/exception/FileMd5Exception.java index 379f977..3dc4574 100644 --- a/library/src/main/java/com/hjq/http/exception/FileMD5Exception.java +++ b/library/src/main/java/com/hjq/http/exception/FileMd5Exception.java @@ -6,16 +6,16 @@ * time : 2019/11/16 * desc : MD5 校验异常 */ -public final class FileMD5Exception extends HttpException { +public final class FileMd5Exception extends HttpException { - private final String mMD5; + private final String mMd5; - public FileMD5Exception(String message, String md5) { + public FileMd5Exception(String message, String md5) { super(message); - mMD5 = md5; + mMd5 = md5; } - public String getMD5() { - return mMD5; + public String getMd5() { + return mMd5; } } \ No newline at end of file diff --git a/library/src/main/java/com/hjq/http/lifecycle/ActivityLifecycle.java b/library/src/main/java/com/hjq/http/lifecycle/ActivityLifecycle.java index 19bf5ea..7eb6992 100644 --- a/library/src/main/java/com/hjq/http/lifecycle/ActivityLifecycle.java +++ b/library/src/main/java/com/hjq/http/lifecycle/ActivityLifecycle.java @@ -25,18 +25,20 @@ public final class ActivityLifecycle implements private Activity mActivity; - public ActivityLifecycle(Activity activity) { + public ActivityLifecycle(@NonNull Activity activity) { mActivity = activity; if (mActivity instanceof LifecycleOwner) { ((LifecycleOwner) mActivity).getLifecycle().addObserver(this); - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - mActivity.registerActivityLifecycleCallbacks(this); - } else { - mActivity.getApplication().registerActivityLifecycleCallbacks(this); - } + return; } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + mActivity.registerActivityLifecycleCallbacks(this); + return; + } + + mActivity.getApplication().registerActivityLifecycleCallbacks(this); } /** 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 eb60896..8a30a96 100644 --- a/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java +++ b/library/src/main/java/com/hjq/http/lifecycle/HttpLifecycleManager.java @@ -18,7 +18,7 @@ public final class HttpLifecycleManager implements LifecycleEventObserver { /** * 绑定组件的生命周期 */ - public static void bind(LifecycleOwner lifecycleOwner) { + public static void register(LifecycleOwner lifecycleOwner) { lifecycleOwner.getLifecycle().addObserver(new HttpLifecycleManager()); } 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 783e7c2..9eaa757 100644 --- a/library/src/main/java/com/hjq/http/request/BodyRequest.java +++ b/library/src/main/java/com/hjq/http/request/BodyRequest.java @@ -250,7 +250,10 @@ private RequestBody createMultipartBody(HttpParams params) { } addFormData(bodyBuilder, String.valueOf(itemKey), itemValue); } - } else if (value instanceof List) { + continue; + } + + if (value instanceof List) { // 如果这是一个 List 集合 List list = (List) value; for (Object itemValue : list) { @@ -259,9 +262,10 @@ private RequestBody createMultipartBody(HttpParams params) { } addFormData(bodyBuilder, key, itemValue); } - } else { - addFormData(bodyBuilder, key, value); + continue; } + + addFormData(bodyBuilder, key, value); } try { @@ -278,22 +282,24 @@ private RequestBody createJsonBody(HttpParams params) { private RequestBody createFormBody(HttpParams params) { FormBody.Builder bodyBuilder = new FormBody.Builder(); - if (!params.isEmpty()) { - for (String key : params.getKeys()) { - Object value = params.get(key); + if (params.isEmpty()) { + return bodyBuilder.build(); + } - if (!(value instanceof List)) { - bodyBuilder.add(key, String.valueOf(value)); - continue; - } + for (String key : params.getKeys()) { + Object value = params.get(key); - List list = (List) value; - for (Object itemValue : list) { - if (itemValue == null) { - continue; - } - bodyBuilder.add(key, String.valueOf(itemValue)); + if (!(value instanceof List)) { + bodyBuilder.add(key, String.valueOf(value)); + continue; + } + + List list = (List) value; + for (Object itemValue : list) { + if (itemValue == null) { + continue; } + bodyBuilder.add(key, String.valueOf(itemValue)); } } return bodyBuilder.build(); 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 7a5892c..03ea2cb 100644 --- a/library/src/main/java/com/hjq/http/request/DownloadRequest.java +++ b/library/src/main/java/com/hjq/http/request/DownloadRequest.java @@ -136,7 +136,7 @@ public DownloadRequest start() { StackTraceElement[] stackTrace = new Throwable().getStackTrace(); - EasyUtils.postDelayed(() -> { + EasyUtils.postDelayedRunnable(() -> { if (!HttpLifecycleManager.isLifecycleActive(getLifecycleOwner())) { // 宿主已被销毁,请求无法进行 EasyLog.printLog(this, "LifecycleOwner has been destroyed and the request cannot be made"); 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 26d61de..a93d37d 100644 --- a/library/src/main/java/com/hjq/http/request/HttpRequest.java +++ b/library/src/main/java/com/hjq/http/request/HttpRequest.java @@ -325,7 +325,9 @@ public void request(@Nullable OnHttpListener listener) { .start(); }; if (mDelayMillis > 0) { - EasyUtils.postDelayed(runnable, mDelayMillis); + // issue 地址:https://github.com/getActivity/EasyHttp/issues/159 + int what = mTag == null ? Integer.MAX_VALUE : mTag.hashCode(); + EasyUtils.postDelayedRunnable(runnable, what, mDelayMillis); } else { runnable.run(); } @@ -357,7 +359,7 @@ public Bean execute(ResponseClass responseClass) throws Exception { EasyLog.printStackTrace(this, new Throwable().getStackTrace()); - Type reflectType = mRequestHandler.getType(responseClass); + Type reflectType = mRequestHandler.getGenericType(responseClass); // 必须将 Call 对象创建放到这里来,否则无法显示请求日志 mCallProxy = new CallProxy(createCall());