【软通动力】HarmonyOS三方件开发指南(11)——Updownfile - HarmonyOS技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

【软通动力】HarmonyOS三方件开发指南(11)——Updownfile

` 本帖最后由 软通动力HOS 于 2021-4-19 15:20 编辑

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




1.2. 使用要求
(1) .在config.json进行网络以及文件读写权限操作

  1. "reqPermissions": [
  2.   {
  3.     "reason": "",
  4.     "name": "ohos.permission.INTERNET"
  5.   },
  6.   {"reason": "",
  7.     "name": "ohos.permission.READ_USER_STORAGE"
  8.   },
  9.   {"reason": "",
  10.     "name": "ohos.permission.READ_MEDIA"
  11.   },
  12.   {"reason": "",
  13.     "name": "ohos.permission.WRITE_USER_STORAGE"
  14.   },
  15.   {"reason": "",
  16.     "name": "ohos.permission.WRITE_MEDIA"
  17.   }
  18. ]
(2) .在实际使用地方进行动态权限申请

  1. String[] per = {"ohos.permission.READ_USER_STORAGE", "ohos.permission.WRITE_MEDIA",
  2. "ohos.permission.READ_MEDIA", "ohos.permission.WRITE_USER_STORAGE"};
  3. requestPermissionsFromUser(per, 0);
1.3. 使用实例介绍UI

2.  UpdownFile使用方法
2.1. 新建工程,增加组件Har包依赖
在应用模块中添加HAR,只需要将updownfile.har复制到entrylibs目录下即可(由于build.gradle中已经依赖的libs目录下的*.har,因此不需要再做修改)。
2.2.  断点续传使用方法介绍
(1). 在AbilitySlice里实现ProgressResponseBody.ProgressListener接口,重写
  1. @Override
  2. public void onPreExecute(long contentLength) {
  3.     // 文件总长只需记录一次,要注意断点续传后的contentLength只是剩余部分的长度
  4.     if (this.contentLength == 0L) {
  5.         this.contentLength = contentLength;
  6.         getUITaskDispatcher().asyncDispatch(new Runnable() {
  7.             @Override
  8.             public void run() {
  9.                 progressBar.setMaxValue((int) (contentLength / 1024));
  10.             }
  11.         });
  12.     }
  13. }
(2).progressBar设置进度更新的方法如下

  1. @Override
  2. public void update(long totalBytes, boolean done) {
  3.     // 注意加上断点的长度
  4.     this.totalBytes = totalBytes + breakPoints;
  5.     getUITaskDispatcher().asyncDispatch(new Runnable() {
  6.         @Override
  7.         public void run() {
  8.             progressBar.setProgressValue((int) (totalBytes + breakPoints) / 1024);
  9.         }
  10.     });
  11.     if (done) {
  12.         // 切换到主线程
  13.         getUITaskDispatcher().asyncDispatch(new Runnable() {
  14.             @Override
  15.             public void run() {
  16.                 LogUtil.Toast(getAbility(), "下载完成");
  17.             }
  18.         });
  19.     }
  20. }
2.3. 初始化下载方法及存储路径

  1. file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "windows.exe");
  2. downloader = new ProgressDownloader(PACKAGE_URL, file, this);
2.4. 具体使用方法
(1). 下载:

  1. breakPoints = 0L;
  2. downloader.download(0L);
  3. LogUtil.Toast(getAbility(), "开始下载");
(2).  暂停,开启拦截器
  1. downloader.pause();
  2. // 存储此时的totalBytes,即断点位置。
  3. breakPoints = totalBytes;
  4. LogUtil.Toast(getAbility(), "下载暂停");
(3). 继续下载,传入开始下载的位置
  1. downloader.download(breakPoints);
  2. LogUtil.Toast(getAbility(), "下载继续");
2.5. 文件上传使用方法
(1). 单文件上传,无需参数
  1. /**
  2. * post请求,上传单个文件
  3. * @param url:url
  4. * @param file:File对象
  5. * @param fileKey:上传参数时file对应的键
  6. * @param fileType:File类型,是image,video,audio,file
  7. * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
  8. */
  9. public static void okHttpUploadFile(String url, File file,String fileKey, String fileType, CallBackUtil callBack) {
  10.     okHttpUploadFile(url, file, fileKey,fileType, null, callBack);
  11. }
(2). 单文件上传,需要参数
  1. /**
  2. * post请求,上传单个文件
  3. * @param url:url
  4. * @param file:File对象
  5. * @param fileKey:上传参数时file对应的键
  6. * @param fileType:File类型,是image,video,audio,file
  7. * @param paramsMap:map集合,封装键值对参数
  8. * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。还可以重写onProgress方法,得到上传进度
  9. */
  10. public static void okHttpUploadFile(String url, File file, String fileKey,String fileType, Map paramsMap, CallBackUtil callBack) {
  11.     okHttpUploadFile(url, file,fileKey, fileType, paramsMap, null, callBack);
  12. }
(3). 多文件上传, List集合形式
  1.   /**
  2. * post请求,上传多个文件,以list集合的形式
  3. * @param url:url
  4. * @param fileList:集合元素是File对象
  5. * @param fileKey:上传参数时fileList对应的键
  6. * @param fileType:File类型,是image,video,audio,file
  7. * @param paramsMap:map集合,封装键值对参数
  8. * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
  9. */
  10. public static void okHttpUploadListFile(String url, Map paramsMap,List fileList, String fileKey, String fileType,  CallBackUtil callBack) {
  11.     okHttpUploadListFile(url, paramsMap,fileList, fileKey, fileType, null, callBack);
  12. }
(4). 多文件上传, Map形式
  1. /**
  2. * post请求,上传多个文件,以map集合的形式
  3. * @param url:url
  4. * @param fileMap:集合key是File对象对应的键,集合value是File对象
  5. * @param fileType:File类型,是image,video,audio,file
  6. * @param paramsMap:map集合,封装键值对参数
  7. * @param headerMap:map集合,封装请求头键值对
  8. * @param callBack:回调接口,onFailure方法在请求失败时调用,onResponse方法在请求成功后调用,这两个方法都执行在UI线程。
  9. */
  10. public static void okHttpUploadMapFile(String url, Map fileMap, String fileType, Map paramsMap, Map headerMap, CallBackUtil callBack) {
  11.     new RequestUtil(METHOD_POST, url,paramsMap, fileMap, fileType,  headerMap, callBack).execute();
  12. }
3.  UpdownFile开发实现
3.1. 新建一个Module
新建一个Module,类型选择HarmonyOS Library,模块名为updownfile,如图
3.2. 新建一个OKhttpUtil类
新建一个OKhttpUtil类,将下载上传方法进行封装



3.3. 新建一个RequestUtil类
RequestUtil实现OkhttpUtil的各种方法

3.4. 新建CallBackUti实现进度更新监听
通过EventHandler发送消息对下载进度实现回调监听,在主线程进行UI更新操作。



3.5. 多任务下载使用方法
(1).多任务下载原理
创建线程池,点击单个下载任务创建子线程并将子线程加入线程池进行管理,将文件信息及更新进度信息存入model进行单独管理,在使用的AblitySlice实现ProgressResponseBody.ProgressListener接口进行进度监听。
(2). 应用层面使用方法
(A). 引入har包,引入方法这里不做介绍
(B). 在AblitySlice实现ProgressResponseBody.ProgressListener接口,并重写接口的两个方法
  1. @Override
  2. public void onPreExecute(long contentLength,int postion) {
  3.     if (list.get(postion).getBean().getContentLength() == 0L) {
  4.         list.get(postion).getBean().setContentLength(contentLength);
  5.         list.get(postion).getBean().getProgressBar().setMaxValue((int) (contentLength / 1024));
  6.     }
  7. }
  8. @Override
  9. public void update(long totalBytes, boolean done,int postion) {
  10.     list.get(postion).getBean().setTotalBytes(totalBytes+list.get(postion).getBean().getBreakPoints());
  11.     getUITaskDispatcher().asyncDispatch(new Runnable() {
  12.         @Override
  13.         public void run() {
  14.          list.get(postion).getBean().getProgressBar().setProgressValue((int) (list.get(postion).getBean().getTotalBytes()) / 1024);
  15.         }
  16.     });
  17.     if (done) {
  18.         // 切换到主线程
  19.         getUITaskDispatcher().asyncDispatch(new Runnable() {
  20.             @Override
  21.             public void run() {
  22.                 LogUtil.Toast(getAbility(), "下载完成");
  23.             }
  24.         });
  25.     }
  26. }
(C) .为ListContainer创建适配器构造数据,实例如下:

  1. listContainer = (ListContainer) findComponentById(ResourceTable.Id_list);
  2. //造数据
  3. FileBean fileBean1 = new FileBean();
  4. fileBean1.setNum(1);
  5. fileBean1.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
  6. fileBean1.setName("下载一.exe");
  7. fileBean1.setBean(new ProgressBean(null,0,0));
  8. FileBean fileBean2 = new FileBean();
  9. fileBean2.setNum(2);
  10. fileBean2.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
  11. fileBean2.setName("下载二.exe");
  12. fileBean2.setBean(new ProgressBean(null,0,0));
  13. FileBean fileBean3 = new FileBean();
  14. fileBean3.setNum(3);
  15. fileBean3.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
  16. fileBean3.setName("下载三.exe");
  17. fileBean3.setBean(new ProgressBean(null,0,0));
  18. FileBean fileBean4 = new FileBean();
  19. fileBean4.setNum(4);
  20. fileBean4.setUrl("https://dl.google.com/dl/android/studio/install/3.5.2.0/android-studio-ide-191.5977832-windows.exe");
  21. fileBean4.setName("下载四.exe");
  22. fileBean4.setBean(new ProgressBean(null,0,0));
  23. list.add(fileBean1);
  24. list.add(fileBean2);
  25. list.add(fileBean3);
  26. list.add(fileBean4);
  27. //初始化适配器
  28. listItemProvider = new ListItemProvider(list,this,this);
  29. //设置适配器
  30. listContainer.setItemProvider(listItemProvider);
D). 在ListContainer的适配器的构造方法中进行线程池初始化
threadTask= new ThreadTask(ability);
E).点击开始下载,创建子线程,并将子线程加入线程池进行管理
threadTask.CreatTask(postion,downloader);
F).暂停下载方法使用如下:
  1. list.get(i).getProgressDownloader().pause();
  2. // 存储此时的totalBytes,即断点位置。  list.get(i).getBean().setBreakPoints(list.get(i).getBean().getTotalBytes());

G). 继续下载方法使用如下:
list.get(i).getProgressDownloader().download(list.get(i).getBean().getBreakPoints());

H). 特别注意,点击暂停时,必须将当前下载的节点进行存储,因为该节点在重新下载时会当作     下载的起始位置。存储方法如下
list.get(i).getBean().setBreakPoints(list.get(i).getBean().getTotalBytes());

3.6.  编译HAR包
利用Gradle可以将HarmonyOS Library库模块构建为HAR,构建HAR的方法如下:
在Gradle构建任务中,HAR包括生产和测试版本,双击PackageDebugHar或PackageReleaseHar任务,构建Debug或Release类型的HAR。
待构建任务完成后,可以在工程目录中的updownfile> bulid > outputs > har目录中,获取生成的HAR。

项目源代码地址:https://github.com/isoftstone-dev/FileDownload_HarmonyOS

©著作权归作者如需转载,请注明出处,否则将追究法律责任
` 4.png 3.png 2.png 1.png

更多回帖

×
发帖