Skip to content

Commit

Permalink
新增支持下载断点续传
Browse files Browse the repository at this point in the history
删除全局下载回调监听
优化请求或者下载回调时机
优化框架内部方法和类命名
  • Loading branch information
getActivity committed Jan 20, 2024
1 parent a7773b6 commit 6abd2a1
Show file tree
Hide file tree
Showing 24 changed files with 440 additions and 217 deletions.
30 changes: 8 additions & 22 deletions HelpDoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

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

* [混淆规则](#混淆规则)

* [使用文档](#使用文档)

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

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

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

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

Expand Down Expand Up @@ -207,23 +205,6 @@ EasyConfig.getInstance()
.addParam("token", data.getData().getToken());
```

#### 混淆规则

```groovy
# OkHttp3
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontwarn okio.**
# 不混淆这个包下的类
-keep class com.xxx.xxx.xxx.xxx.** {
<fields>;
}
```

# 使用文档

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

@Override
Expand All @@ -419,7 +402,8 @@ EasyHttp.download(this)

@Override
public void onDownloadFail(File file, Throwable throwable) {
toast("下载出错:" + throwable.getMessage());
toast("下载失败:" + throwable.getMessage());
file.delete();
}

@Override
Expand Down Expand Up @@ -705,14 +689,16 @@ EasyConfig.getInstance().addHeader("key", "value");
EasyConfig.getInstance().removeHeader("key");
```

#### 如何定义全局的动态参数
#### 如何动态添加全局的参数或者请求头

```java
EasyConfig.getInstance().setInterceptor(new IRequestInterceptor() {

@Override
public void interceptArguments(@NonNull HttpRequest<?> httpRequest, @NonNull HttpParams params, @NonNull HttpHeaders headers) {
// 添加请求头
headers.put("key", "value");
// 添加参数
params.put("key", "value");
}
});
Expand Down
60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

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

![](picture/demo_code.png)

Expand Down Expand Up @@ -61,7 +61,7 @@ android {
dependencies {
// 网络请求框架:https://github.com/getActivity/EasyHttp
implementation 'com.github.getActivity:EasyHttp:12.6'
implementation 'com.github.getActivity:EasyHttp:12.8'
// OkHttp 框架:https://github.com/square/okhttp
// noinspection GradleDependency
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
Expand All @@ -72,30 +72,64 @@ dependencies {

#### 框架混淆规则

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

```text
# OkHttp3 框架混淆规则
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontwarn okio.**
```

* EasyHttp 框架混淆规则

```text
# EasyHttp 框架混淆规则
-keep class com.hjq.http.** {*;}
```

* 不混淆实现 OnHttpListener 接口的类

```text
# 必须要加上此规则,否则会导致泛型解析失败
-keep public class * implements com.hjq.http.listener.OnHttpListener {
*;
}
```

* 不混淆某个包下的 Bean 类

```text
# 必须要加上此规则,否则可能会导致 Bean 类的字段无法解析成后台返回的字段,xxx 请替换成对应包名
-keep class com.xxx.xxx.xxx.xxx.** {
<fields>;
}
```

* 以上混淆规则,可以在主模块的 `proguard-rules.pro` 文件中加入

## [框架的具体用法请点击这里查看](HelpDoc.md)

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

| 功能或细节 | [EasyHttp](https://github.com/getActivity/EasyHttp) | [Retrofit](https://github.com/square/retrofit) | [OkGo](https://github.com/jeasonlzy/okhttp-OkGo) |
| :----: | :------: | :-----: | :-----: |
| 对应版本 | 12.6 | 2.9.0 | 3.0.4 |
| 对应版本 | 12.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 包大小** | 93 KB | 123 KB | 131 KB |
| **aar 包大小** | 95 KB | 123 KB | 131 KB |
| minSdk 要求 | API 14+ | API 21+ | API 14+ |
| 配置多域名 ||||
| **动态 Host** ||||
| 全局参数 ||||
| 日志打印 ||||
| 超时重试 ||||
| **请求缓存** ||||
| **下载校验** ||||
| **配置 Http 缓存** ||||
| **下载文件校验** ||||
| **极速下载** ||||
| **下载断点续传** ||||
| 上传进度监听 ||||
| Json 参数提交 ||||
| Json 日志打印格式化 ||||
Expand Down Expand Up @@ -283,18 +317,6 @@ EasyHttp.post(this)

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

#### 广告区

* 我现在任腾讯云服务器推广大使,大家如果有购买服务器的需求,可以通过下面的链接购买

[![](https://upload-dianshi-1255598498.file.myqcloud.com/upload/nodir/345X200-9ae456f58874df499adf7c331c02cb0fed12b81d.jpg)](https://curl.qcloud.com/A6cYskvv)

[【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中](https://curl.qcloud.com/A6cYskvv)

[![](https://upload-dianshi-1255598498.file.myqcloud.com/345-200-b28f7dee9552f4241ea6a543f15a9798049701d4.jpg)](https://curl.qcloud.com/up4fQsdn)

[【腾讯云】中小企业福利专场,多款刚需产品,满足企业通用场景需求](https://curl.qcloud.com/up4fQsdn)

## License

```text
Expand Down
19 changes: 12 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId 'com.hjq.easy.demo'
minSdkVersion 21
targetSdkVersion 31
versionCode 1206
versionName '12.6'
versionCode 1208
versionName '12.8'
}

// 支持 JDK 1.8
Expand Down Expand Up @@ -73,28 +73,33 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.12.13'

// 吐司框架:https://github.com/getActivity/Toaster
implementation 'com.github.getActivity:Toaster:12.5'
implementation 'com.github.getActivity:Toaster:12.6'

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

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

// Gson 解析容错:https://github.com/getActivity/GsonFactory
implementation 'com.github.getActivity:GsonFactory:9.5'
// 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:9.0'
// Kotlin 反射库:用于反射 Kotlin data class 类对象
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.5.10'

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

// 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'
debugImplementation 'com.github.getActivity:Logcat:11.82'

// OkHttp 抓包框架:https://github.com/lygttpod/AndroidMonitor
// debugImplementation 'io.github.lygttpod:monitor:0.0.7'
Expand Down
7 changes: 7 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
-dontwarn okhttp3.**
-dontwarn okio.**

# EasyHttp
-keep class com.hjq.http.** {*;}
# 必须要加上此规则,否则会导致泛型解析失败
-keep public class * implements com.hjq.http.listener.OnHttpListener {
*;
}

# 不混淆这个包下的类
-keep class com.hjq.easy.demo.http.** {
<fields>;
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/hjq/easy/demo/AppApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public void onParseObjectException(TypeToken<?> typeToken, String fieldName, Jso
}

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

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

Expand Down
73 changes: 39 additions & 34 deletions app/src/main/java/com/hjq/easy/demo/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
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.listener.HttpCallbackProxy;
import com.hjq.http.listener.OnDownloadListener;
import com.hjq.http.listener.OnUpdateListener;
Expand Down Expand Up @@ -164,21 +163,23 @@ public void onHttpSuccess(HttpData<SearchBlogsApi.Bean> result) {
return;
}

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

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

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

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

@Override
Expand All @@ -284,10 +292,7 @@ public void onDownloadSuccess(File file) {
@Override
public void onDownloadFail(File file, Throwable throwable) {
Toaster.show("下载失败:" + throwable.getMessage());
if (throwable instanceof FileMd5Exception) {
// 如果是文件 md5 校验失败,则删除文件
file.delete();
}
file.delete();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.hjq.easy.demo.http.api;

import androidx.annotation.NonNull;

import com.hjq.http.config.IRequestApi;
import com.hjq.http.config.IRequestServer;

import java.io.File;

/**
Expand Down
Loading

0 comments on commit 6abd2a1

Please sign in to comment.