
01
UpDownfile 功能介绍
UpDownfile 基于 Okhttp 为基础进行二次封装,是一款非常好用的文件上传下载框架,该框架功能强大,主要包含两方面功能:
文件下载带进度展示:
单任务下载:分为带参数和不带参数,包括暂停下载、继续下载功能。
多任务下载:分为带参数和不带参数,包括暂停下载、继续下载功能。
文件上传带进度展示:
单任务上传:分为带参数和不带参数,包括暂停上传、继续上传功能。
多任务上传:分为带参数和不带参数,包括暂停上传、继续上传功能。


①使用要求
"reqPermissions": [
{
"reason": "",
"name": "ohos.permission.INTERNET"
},
{"reason": "",
"name": "ohos.permission.READ_USER_STORAGE"
},
{"reason": "",
"name": "ohos.permission.READ_MEDIA"
},
{"reason": "",
"name": "ohos.permission.WRITE_USER_STORAGE"
},
{"reason": "",
"name": "ohos.permission.WRITE_MEDIA"
}
]
String[] per = {"ohos.permission.READ_USER_STORAGE", "ohos.permission.WRITE_MEDIA",
"ohos.permission.READ_MEDIA", "ohos.permission.WRITE_USER_STORAGE"};
requestPermissionsFromUser(per, 0);
②使用实例介绍 UI

02
UpdownFile 使用方法
①新建工程,增加组件 Har 包依赖
在应用模块中添加 HAR,只需要将 updownfile.har 复制到 entry\libs 目录下即可(由于 build.gradle 中已经依赖的 libs 目录下的 *.har,因此不需要再做修改)。
②断点续传使用方法介绍
@Override
public void onPreExecute(long contentLength) {
// 文件总长只需记录一次,要注意断点续传后的contentLength只是剩余部分的长度
if (this.contentLength == 0L) {
this.contentLength = contentLength;
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
progressBar.setMaxValue((int) (contentLength / 1024));
}
});
}
}
progressBar 设置进度更新的方法如下:
@Override
public void update(long totalBytes, boolean done) {
// 注意加上断点的长度
this.totalBytes = totalBytes + breakPoints;
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
progressBar.setProgressValue((int) (totalBytes + breakPoints) / 1024);
}
});
if (done) {
// 切换到主线程
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
LogUtil.Toast(getAbility(), "下载完成");
}
});
}
}
③初始化下载方法及存储路径
代码如下:
file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "windows.exe");
downloader = new ProgressDownloader(PACKAGE_URL, file, this);
④具体使用方法
breakPoints = 0L;
downloader.download(0L);
LogUtil.Toast(getAbility(), "开始下载");
downloader.pause();
// 存储此时的totalBytes,即断点位置。
breakPoints = totalBytes;
LogUtil.Toast(getAbility(), "下载暂停");
downloader.download(breakPoints);
LogUtil.Toast(getAbility(), "下载继续");
⑤文件上传使用方法
/**
* post请求,上传单个文件
* @param url:url
* @param file:File对象
* @param fileKey:上传参数时file对应的键
* @param fileType:File类型,是image,video,audio,file
* @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
*/
public static void okHttpUploadFile(String url, File file,String fileKey, String fileType, CallBackUtil callBack) {
okHttpUploadFile(url, file, fileKey,fileType, null, callBack);
}
/**
* post请求,上传单个文件
* @param url:url
* @param file:File对象
* @param fileKey:上传参数时file对应的键
* @param fileType:File类型,是image,video,audio,file
* @param paramsMap:map集合,封装键值对参数
* @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
*/
public static void okHttpUploadFile(String url, File file, String fileKey,String fileType, Map<String, String> paramsMap, CallBackUtil callBack) {
okHttpUploadFile(url, file,fileKey, fileType, paramsMap, null, callBack);
}
/**
* post请求,上传多个文件,以list集合的形式
* @param url:url
* @param fileList:集合元素是File对象
* @param fileKey:上传参数时fileList对应的键
* @param fileType:File类型,是image,video,audio,file
* @param paramsMap:map集合,封装键值对参数
* @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
*/
public static void okHttpUploadListFile(String url, Map<String, String> paramsMap,List<File> fileList, String fileKey, String fileType, CallBackUtil callBack) {
okHttpUploadListFile(url, paramsMap,fileList, fileKey, fileType, null, callBack);
}
/**
* post请求,上传多个文件,以map集合的形式
* @param url:url
* @param fileMap:集合key是File对象对应的键,集合value是File对象
* @param fileType:File类型,是image,video,audio,file
* @param paramsMap:map集合,封装键值对参数
* @param headerMap:map集合,封装请求头键值对
* @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
*/
public static void okHttpUploadMapFile(String url, Map<String, File> fileMap, String fileType, Map<String, String> paramsMap, Map<String, String> headerMap, CallBackUtil callBack) {
new RequestUtil(METHOD_POST, url,paramsMap, fileMap, fileType, headerMap, callBack).execute();
}
03
UpdownFile 开发实现
①新建一个 Module

②新建一个 OKhttpUtil 类

③新建一个 RequestUtil 类

④新建 CallBackUti 实现进度更新监听

⑤多任务下载使用方法
(1).多任务下载原理
创建线程池,点击单个下载任务创建子线程并将子线程加入线程池进行管理,将文件信息及更新进度信息存入 model 进行单独管理,在使用的 AblitySlice 实现 ProgressResponseBody.ProgressListener 接口进行进度监听。
(2).应用层面使用方法
(A).引入 har 包,引入方法这里不做介绍
@Override
public void onPreExecute(long contentLength,int postion) {
if (list.get(postion).getBean().getContentLength() == 0L) {
list.get(postion).getBean().setContentLength(contentLength);
list.get(postion).getBean().getProgressBar().setMaxValue((int) (contentLength / 1024));
}
}
@Override
public void update(long totalBytes, boolean done,int postion) {
list.get(postion).getBean().setTotalBytes(totalBytes+list.get(postion).getBean().getBreakPoints());
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
list.get(postion).getBean().getProgressBar().setProgressValue((int) (list.get(postion).getBean().getTotalBytes()) / 1024);
}
});
if (done) {
// 切换到主线程
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
LogUtil.Toast(getAbility(), "下载完成");
}
});
}
}
listContainer = (ListContainer) findComponentById(ResourceTable.Id_list);
//造数据
FileBean fileBean1 = new FileBean();
fileBean1.setNum(1);
fileBean1.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
fileBean1.setName("下载一.exe");
fileBean1.setBean(new ProgressBean(null,0,0));
FileBean fileBean2 = new FileBean();
fileBean2.setNum(2);
fileBean2.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
fileBean2.setName("下载二.exe");
fileBean2.setBean(new ProgressBean(null,0,0));
FileBean fileBean3 = new FileBean();
fileBean3.setNum(3);
fileBean3.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
fileBean3.setName("下载三.exe");
fileBean3.setBean(new ProgressBean(null,0,0));
FileBean fileBean4 = new FileBean();
fileBean4.setNum(4);
fileBean4.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
fileBean4.setName("下载四.exe");
fileBean4.setBean(new ProgressBean(null,0,0));
list.add(fileBean1);
list.add(fileBean2);
list.add(fileBean3);
list.add(fileBean4);
//初始化适配器
listItemProvider = new ListItemProvider(list,this,this);
//设置适配器
listContainer.setItemProvider(listItemProvider);
(D).在 ListContainer 的适配器的构造方法中进行线程池初始化:
threadTask= new ThreadTask(ability);
(E).点击开始下载,创建子线程,并将子线程加入线程池进行管理:
threadTask.CreatTask(postion,downloader);
list.get(i).getProgressDownloader().pause();
// 存储此时的totalBytes,即断点位置。 list.get(i).getBean().setBreakPoints(list.get(i).getBean().getTotalBytes());
(G).继续下载方法使用如下:
list.get(i).getProgressDownloader().download(list.get(i).getBean().getBreakPoints());
存储方法如下:
list.get(i).getBean().setBreakPoints(list.get(i).getBean().getTotalBytes());
⑥编译 HAR 包
利用 Gradle 可以将 HarmonyOS Library 库模块构建为 HAR。
构建 HAR 的方法如下:
在 Gradle 构建任务中,HAR 包括生产和测试版本,双击 PackageDebugHar 或 PackageReleaseHar 任务,构建 Debug 或 Release 类型的 HAR。

https://github.com/isoftstone-dev/FileDownload_HarmonyOS
欢迎交流:HWIS-HOS@isoftstone.com
👇点击关注鸿蒙技术社区👇
专注开源技术,共建鸿蒙生态

点“阅读原文”了解更多




