Skip to content

Commit 6abd2a1

Browse files
committed
新增支持下载断点续传
删除全局下载回调监听 优化请求或者下载回调时机 优化框架内部方法和类命名
1 parent a7773b6 commit 6abd2a1

24 files changed

+440
-217
lines changed

HelpDoc.md

+8-22
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
* [框架初始化](#框架初始化)
1212

13-
* [混淆规则](#混淆规则)
14-
1513
* [使用文档](#使用文档)
1614

1715
* [配置接口](#配置接口)
@@ -36,7 +34,7 @@
3634

3735
* [如何添加或者删除全局参数](#如何添加或者删除全局参数)
3836

39-
* [如何定义全局的动态参数](#如何定义全局的动态参数)
37+
* [如何动态添加全局的参数或者请求头](#如何动态添加全局的参数或者请求头)
4038

4139
* [如何在请求中忽略某个全局参数](#如何在请求中忽略某个全局参数)
4240

@@ -207,23 +205,6 @@ EasyConfig.getInstance()
207205
.addParam("token", data.getData().getToken());
208206
```
209207

210-
#### 混淆规则
211-
212-
```groovy
213-
# OkHttp3
214-
-keepattributes Signature
215-
-keepattributes *Annotation*
216-
-keep class okhttp3.** { *; }
217-
-keep interface okhttp3.** { *; }
218-
-dontwarn okhttp3.**
219-
-dontwarn okio.**
220-
221-
# 不混淆这个包下的类
222-
-keep class com.xxx.xxx.xxx.xxx.** {
223-
<fields>;
224-
}
225-
```
226-
227208
# 使用文档
228209

229210
#### 配置接口
@@ -399,6 +380,8 @@ EasyHttp.download(this)
399380
//.url("https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk")
400381
.url("http://dldir1.qq.com/weixin/android/weixin708android1540.apk")
401382
.md5("2E8BDD7686474A7BC4A51ADC3667CABF")
383+
// 设置断点续传(默认不开启)
384+
//.resumableTransfer(true)
402385
.listener(new OnDownloadListener() {
403386

404387
@Override
@@ -419,7 +402,8 @@ EasyHttp.download(this)
419402

420403
@Override
421404
public void onDownloadFail(File file, Throwable throwable) {
422-
toast("下载出错:" + throwable.getMessage());
405+
toast("下载失败:" + throwable.getMessage());
406+
file.delete();
423407
}
424408

425409
@Override
@@ -705,14 +689,16 @@ EasyConfig.getInstance().addHeader("key", "value");
705689
EasyConfig.getInstance().removeHeader("key");
706690
```
707691

708-
#### 如何定义全局的动态参数
692+
#### 如何动态添加全局的参数或者请求头
709693

710694
```java
711695
EasyConfig.getInstance().setInterceptor(new IRequestInterceptor() {
712696

713697
@Override
714698
public void interceptArguments(@NonNull HttpRequest<?> httpRequest, @NonNull HttpParams params, @NonNull HttpHeaders headers) {
699+
// 添加请求头
715700
headers.put("key", "value");
701+
// 添加参数
716702
params.put("key", "value");
717703
}
718704
});

README.md

+41-19
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
* 博客地址:[网络请求,如斯优雅](https://www.jianshu.com/p/93cd59dec002)
66

7-
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处下载Demo](https://github.com/getActivity/EasyHttp/releases/download/12.6/EasyHttp.apk)
7+
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处下载Demo](https://github.com/getActivity/EasyHttp/releases/download/12.8/EasyHttp.apk)
88

99
![](picture/demo_code.png)
1010

@@ -61,7 +61,7 @@ android {
6161
6262
dependencies {
6363
// 网络请求框架:https://github.com/getActivity/EasyHttp
64-
implementation 'com.github.getActivity:EasyHttp:12.6'
64+
implementation 'com.github.getActivity:EasyHttp:12.8'
6565
// OkHttp 框架:https://github.com/square/okhttp
6666
// noinspection GradleDependency
6767
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
@@ -72,30 +72,64 @@ dependencies {
7272

7373
#### 框架混淆规则
7474

75-
* 在混淆规则文件 `proguard-rules.pro` 中加入
75+
* OkHttp3 框架混淆规则
7676

7777
```text
78+
# OkHttp3 框架混淆规则
79+
-keepattributes Signature
80+
-keepattributes *Annotation*
81+
-keep class okhttp3.** { *; }
82+
-keep interface okhttp3.** { *; }
83+
-dontwarn okhttp3.**
84+
-dontwarn okio.**
85+
```
86+
87+
* EasyHttp 框架混淆规则
88+
89+
```text
90+
# EasyHttp 框架混淆规则
7891
-keep class com.hjq.http.** {*;}
7992
```
8093

94+
* 不混淆实现 OnHttpListener 接口的类
95+
96+
```text
97+
# 必须要加上此规则,否则会导致泛型解析失败
98+
-keep public class * implements com.hjq.http.listener.OnHttpListener {
99+
*;
100+
}
101+
```
102+
103+
* 不混淆某个包下的 Bean 类
104+
105+
```text
106+
# 必须要加上此规则,否则可能会导致 Bean 类的字段无法解析成后台返回的字段,xxx 请替换成对应包名
107+
-keep class com.xxx.xxx.xxx.xxx.** {
108+
<fields>;
109+
}
110+
```
111+
112+
* 以上混淆规则,可以在主模块的 `proguard-rules.pro` 文件中加入
113+
81114
## [框架的具体用法请点击这里查看](HelpDoc.md)
82115

83116
### 不同网络请求框架之间的对比
84117

85118
| 功能或细节 | [EasyHttp](https://github.com/getActivity/EasyHttp) | [Retrofit](https://github.com/square/retrofit) | [OkGo](https://github.com/jeasonlzy/okhttp-OkGo) |
86119
| :----: | :------: | :-----: | :-----: |
87-
| 对应版本 | 12.6 | 2.9.0 | 3.0.4 |
120+
| 对应版本 | 12.8 | 2.9.0 | 3.0.4 |
88121
| 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) |
89-
| **aar 包大小** | 93 KB | 123 KB | 131 KB |
122+
| **aar 包大小** | 95 KB | 123 KB | 131 KB |
90123
| minSdk 要求 | API 14+ | API 21+ | API 14+ |
91124
| 配置多域名 ||||
92125
| **动态 Host** ||||
93126
| 全局参数 ||||
94127
| 日志打印 ||||
95128
| 超时重试 ||||
96-
| **请求缓存** ||||
97-
| **下载校验** ||||
129+
| **配置 Http 缓存** ||||
130+
| **下载文件校验** ||||
98131
| **极速下载** ||||
132+
| **下载断点续传** ||||
99133
| 上传进度监听 ||||
100134
| Json 参数提交 ||||
101135
| Json 日志打印格式化 ||||
@@ -283,18 +317,6 @@ EasyHttp.post(this)
283317

284318
* [WanAndroid](https://www.wanandroid.com/)
285319

286-
#### 广告区
287-
288-
* 我现在任腾讯云服务器推广大使,大家如果有购买服务器的需求,可以通过下面的链接购买
289-
290-
[![](https://upload-dianshi-1255598498.file.myqcloud.com/upload/nodir/345X200-9ae456f58874df499adf7c331c02cb0fed12b81d.jpg)](https://curl.qcloud.com/A6cYskvv)
291-
292-
[【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中](https://curl.qcloud.com/A6cYskvv)
293-
294-
[![](https://upload-dianshi-1255598498.file.myqcloud.com/345-200-b28f7dee9552f4241ea6a543f15a9798049701d4.jpg)](https://curl.qcloud.com/up4fQsdn)
295-
296-
[【腾讯云】中小企业福利专场,多款刚需产品,满足企业通用场景需求](https://curl.qcloud.com/up4fQsdn)
297-
298320
## License
299321

300322
```text

app/build.gradle

+12-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId 'com.hjq.easy.demo'
1515
minSdkVersion 21
1616
targetSdkVersion 31
17-
versionCode 1206
18-
versionName '12.6'
17+
versionCode 1208
18+
versionName '12.8'
1919
}
2020

2121
// 支持 JDK 1.8
@@ -73,28 +73,33 @@ dependencies {
7373
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
7474

7575
// 吐司框架:https://github.com/getActivity/Toaster
76-
implementation 'com.github.getActivity:Toaster:12.5'
76+
implementation 'com.github.getActivity:Toaster:12.6'
7777

7878
// 权限请求框架:https://github.com/getActivity/XXPermissions
7979
implementation 'com.github.getActivity:XXPermissions:18.5'
8080

8181
// 标题栏框架:https://github.com/getActivity/TitleBar
8282
implementation 'com.github.getActivity:TitleBar:10.5'
8383

84+
// Gson 解析容错:https://github.com/getActivity/GsonFactory
85+
implementation 'com.github.getActivity:GsonFactory:9.5'
8486
// Json 解析框架:https://github.com/google/gson
8587
implementation 'com.google.code.gson:gson:2.10.1'
86-
// Gson 解析容错:https://github.com/getActivity/GsonFactory
87-
implementation 'com.github.getActivity:GsonFactory:9.0'
88+
// Kotlin 反射库:用于反射 Kotlin data class 类对象
89+
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.10'
8890

8991
// 腾讯 MMKV:https://github.com/Tencent/MMKV
90-
implementation 'com.tencent:mmkv-static:1.2.14'
92+
implementation ('com.tencent:mmkv-static:1.3.2') {
93+
// 避免版本不一致导致的依赖冲突,从而导致编译报错
94+
exclude group: 'androidx.annotation', module: 'annotation'
95+
}
9196

9297
// Bugly 异常捕捉:https://bugly.qq.com/docs/user-guide/instruction-manual-android/?v=20190418140644
9398
implementation 'com.tencent.bugly:crashreport:4.1.9'
9499
implementation 'com.tencent.bugly:nativecrashreport:3.9.2'
95100

96101
// 日志调试框架:https://github.com/getActivity/Logcat
97-
debugImplementation 'com.github.getActivity:Logcat:11.8'
102+
debugImplementation 'com.github.getActivity:Logcat:11.82'
98103

99104
// OkHttp 抓包框架:https://github.com/lygttpod/AndroidMonitor
100105
// debugImplementation 'io.github.lygttpod:monitor:0.0.7'

app/proguard-rules.pro

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
-dontwarn okhttp3.**
3333
-dontwarn okio.**
3434

35+
# EasyHttp
36+
-keep class com.hjq.http.** {*;}
37+
# 必须要加上此规则,否则会导致泛型解析失败
38+
-keep public class * implements com.hjq.http.listener.OnHttpListener {
39+
*;
40+
}
41+
3542
# 不混淆这个包下的类
3643
-keep class com.hjq.easy.demo.http.** {
3744
<fields>;

app/src/main/java/com/hjq/easy/demo/AppApplication.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ public void onParseObjectException(TypeToken<?> typeToken, String fieldName, Jso
4646
}
4747

4848
@Override
49-
public void onParseListException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken) {
49+
public void onParseListItemException(TypeToken<?> typeToken, String fieldName, JsonToken listItemJsonToken) {
5050
handlerGsonParseException("解析 List 异常:" + typeToken + "#" + fieldName + ",后台返回的条目类型为:" + listItemJsonToken);
5151
}
5252

5353
@Override
54-
public void onParseMapException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) {
54+
public void onParseMapItemException(TypeToken<?> typeToken, String fieldName, String mapItemKey, JsonToken mapItemJsonToken) {
5555
handlerGsonParseException("解析 Map 异常:" + typeToken + "#" + fieldName + ",mapItemKey = " + mapItemKey + ",后台返回的条目类型为:" + mapItemJsonToken);
5656
}
5757

app/src/main/java/com/hjq/easy/demo/MainActivity.java

+39-34
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.hjq.easy.demo.http.model.HttpData;
2424
import com.hjq.http.EasyHttp;
2525
import com.hjq.http.EasyUtils;
26-
import com.hjq.http.exception.FileMd5Exception;
2726
import com.hjq.http.listener.HttpCallbackProxy;
2827
import com.hjq.http.listener.OnDownloadListener;
2928
import com.hjq.http.listener.OnUpdateListener;
@@ -164,21 +163,23 @@ public void onHttpSuccess(HttpData<SearchBlogsApi.Bean> result) {
164163
return;
165164
}
166165

166+
/*
167167
// 如果是放到外部存储目录下则需要适配分区存储
168-
// String fileName = "EasyHttp.png";
169-
// File file;
170-
// Uri outputUri;
171-
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
172-
// // 适配 Android 10 分区存储特性
173-
// ContentValues values = new ContentValues();
174-
// // 设置显示的文件名
175-
// values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
176-
// // 生成一个新的 uri 路径
177-
// outputUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
178-
// file = new FileContentResolver(getContentResolver(), outputUri, fileName);
179-
// } else {
180-
// file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName);
181-
// }
168+
String fileName = "EasyHttp.png";
169+
File file;
170+
Uri outputUri;
171+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
172+
// 适配 Android 10 分区存储特性
173+
ContentValues values = new ContentValues();
174+
// 设置显示的文件名
175+
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
176+
// 生成一个新的 uri 路径
177+
outputUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
178+
file = new FileContentResolver(getContentResolver(), outputUri, fileName);
179+
} else {
180+
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName);
181+
}
182+
*/
182183

183184
// 如果是放到外部存储的应用专属目录则不需要适配分区存储特性
184185
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "我是测试专用的图片.png");
@@ -236,22 +237,27 @@ public void onUpdateEnd(Call call) {
236237
return;
237238
}
238239

240+
/*
239241
// 如果是放到外部存储目录下则需要适配分区存储
240-
// String fileName = "微信 8.0.15.apk";
241-
//
242-
// File file;
243-
// Uri outputUri;
244-
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
245-
// // 适配 Android 10 分区存储特性
246-
// ContentValues values = new ContentValues();
247-
// // 设置显示的文件名
248-
// values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
249-
// // 生成一个新的 uri 路径
250-
// outputUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
251-
// file = new FileContentResolver(getContentResolver(), outputUri, fileName);
252-
// } else {
253-
// file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
254-
// }
242+
String fileName = "微信 8.0.15.apk";
243+
244+
File file;
245+
Uri outputUri;
246+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
247+
// 适配 Android 10 分区存储特性
248+
ContentValues values = new ContentValues();
249+
// 设置显示的文件名
250+
values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
251+
// 生成一个新的 uri 路径
252+
// 注意这里使用 ContentResolver 插入的时候都会生成新的 Uri
253+
// 解决方式将 ContentValues 和 Uri 作为 key 和 value 进行持久化关联
254+
// outputUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
255+
outputUri = ContentResolverUriStore.insert(this, Downloads.EXTERNAL_CONTENT_URI, values);
256+
file = new FileContentResolver(getContentResolver(), outputUri, fileName);
257+
} else {
258+
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
259+
}
260+
*/
255261

256262
// 如果是放到外部存储的应用专属目录则不需要适配分区存储特性
257263
File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "微信 8.0.15.apk");
@@ -262,6 +268,8 @@ public void onUpdateEnd(Call call) {
262268
//.url("https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk")
263269
.url("https://dldir1.qq.com/weixin/android/weixin8015android2020_arm64.apk")
264270
.md5("b05b25d4738ea31091dd9f80f4416469")
271+
// 设置断点续传(默认不开启)
272+
.resumableTransfer(true)
265273
.listener(new OnDownloadListener() {
266274

267275
@Override
@@ -284,10 +292,7 @@ public void onDownloadSuccess(File file) {
284292
@Override
285293
public void onDownloadFail(File file, Throwable throwable) {
286294
Toaster.show("下载失败:" + throwable.getMessage());
287-
if (throwable instanceof FileMd5Exception) {
288-
// 如果是文件 md5 校验失败,则删除文件
289-
file.delete();
290-
}
295+
file.delete();
291296
}
292297

293298
@Override

app/src/main/java/com/hjq/easy/demo/http/api/UpdateImageApi.java

-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package com.hjq.easy.demo.http.api;
22

33
import androidx.annotation.NonNull;
4-
54
import com.hjq.http.config.IRequestApi;
65
import com.hjq.http.config.IRequestServer;
7-
86
import java.io.File;
97

108
/**

0 commit comments

Comments
 (0)