OpenHarmony——JS API 之下载 原创 精华

深开鸿
发布于 2022-4-21 10:45
浏览
4收藏

作者:吴进涛

1.前言

​ 本文主要是对于开发文档 JS API 中 下载部分的粗略见解和项目实践,方便更快的切入开发工作,构建应用,对应文档链接:https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-request-0000001123753962#section22193548205

2.API 简介:

2.1使用前准备工作

引入依赖:import request from ‘@ohos.request’;

配置权限:在config.json文件中配置如下权限:

OpenHarmony——JS API 之下载-鸿蒙开发者社区

注意默认支持https,如果要支持http,需要在config.json里增加network标签,属性标识 “cleartextTraffic”: true。即:

  • "deviceConfig": {
        "default": {
            "network": {
                "cleartextTraffic": true
            }
        }
    },
    

2.2入参配置和下载任务信息列表

​ (1)入参配置 DownloadConfig 如下表:

  • 名称 类型 必填 说明
    url string 资源地址。
    header object 添加要包含在下载请求中的HTTP或HTTPS标志头。
    enableMetered boolean 允许在按流量计费的连接下下载。
    enableRoaming boolean 允许在漫游网络中下载。
    description string 设置下载会话的描述。
    filePath (BETA)7+ string 设置下载路径(默认在internal://cache/路径下)。filePath:‘workspace/test.txt’:默认路径下创建workspace路径,并将文件存储在workspace路径下。filePath:‘test.txt’:将文件存储在默认路径下。filePath:‘workspace/’:默认路径下创建workspace路径,并将文件存储在workspace路径下。
    networkType number 设置允许下载的网络类型。
    title string 设置下载会话标题。

​ (2)下载任务信息列表 DownloadInfo 如下图:

  • 名称 类型 必填 说明
    downloadId number 下载的文件ID。
    failedReason number 下载失败原因,可以是任何ERROR_*常量。
    fileName string 下载的文件名。
    filePath string 存储文件的URI。
    pausedReason number 会话暂停的原因,可以是任何PAUSED_*常量。
    status number 下载状态代码,可以是任何SESSION_*常量。
    targetURI string 下载文件的URI。
    downloadTitle string 下载的文件的标题。
    downloadTotalBytes number 下载的文件的总大小(int bytes)。
    description string 待下载文件的描述信息。
    downloadedBytes number 实时下载大小(int bytes)。

2.3 下载API 中方法

​ 下载API 中的方法和事件监听 如下图:由于条件所限,本次只谈API 6 及以下方法。

OpenHarmony——JS API 之下载-鸿蒙开发者社区

2.3.1 request.download

​ 作为下载的核心 request.download 有两种使用方式,分别为

​ (1)使用promise形式返回结果,如下:

  • request.download({ url: 'https://xxxx/xxxx.hap' }).then((data) => {
        downloadTask = data;
    }).catch((err) => {
        console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
    })
    

​ (2) 使用callback形式返回结果,如下:

  • request.download({ url: 'https://xxxx/xxxxx.hap', 
                      filePath: 'xxx/xxxxx.hap'}, (err, data) => {
        if (err) {
            console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
            return;
        }
        downloadTask = data;
    });
    

​ 以上两种均为异步方法

2.3.2 on(‘progress’)

开启下载任务监听,异步方法,使用callback形式返回结果。此方法可以用来配合界面直观形象的展示下载进度。

  • 参数:

    参数名 参数类型 必填 说明
    type string 取消订阅的事件类型,取值为’progress’(下载的进度信息)。
    callback function 下载任务的回调函数。

    回调函数的参数:

    参数名 类型 必填 说明
    receivedSize number 当前下载的进度。
    totalSize number 下载文件的总大小。
  • 示例:

    request.download({ url: 'https://xxxx/xxxx.hap' }, (err, data)=> {  
        if (err) {               
        	console.error('Fail to request download. Cause:' + err);       
        	return;    
        }    
        downloadTask = data;        
        downloadTask .off('progress', download_callback);
    });
    
    download_callback(receivedSize, totalSize) {   
    	console.info("download receivedSize:" + receivedSize + " totalSize:" + totalSize);
    }
    

2.3.3 off(‘progress’)

​ 关闭下载任务监听,异步方法,使用callback形式返回结果。

  • 参数:

    参数名 参数类型 必填 说明
    type string 取消订阅的事件类型,取值为’progress’(下载的进度信息)。
    callback function 下载任务的回调函数。

    回调函数的参数:

    参数名 类型 必填 说明
    receivedSize number 当前下载的进度。
    totalSize number 下载文件的总大小。
  • 示例:

    request.download({ url: 'https://xxxx/xxxx.hap' }, (err, data)=> {     
        if (err) {               
        	console.error('Fail to request download. Cause:' + err);       
        	return;   
        }    
        downloadTask = data;       
        downloadTask .off('progress', download_callback);
    });
    
    download_callback(receivedSize, totalSize) {   
    	console.info("download receivedSize:" + receivedSize + " totalSize:" + totalSize);
    }
    

2.3.4 remove

​ 移除下载的任务,同样为异步方法,根据返回结果的形式不同,同样分为两种

​ (1)使用promise形式返回结果

  • downloadTask.remove().then((result) => {
        if (result) {
            console.info('Download task removed.');
        } else {
            console.error('Failed to remove the download task.');
        }
    }).catch ((err) => {
        console.error('Failed to remove the download task.');
    });
    

(2)使用callback形式返回结果

  • downloadTask.remove((err, result)=>{
        if(err) {
            console.error('Failed to remove the download task.');
            return;
        } 
        if (result) {
            console.info('Download task removed.');
        } else {
            console.error('Failed to remove the download task.');
        } 
    });
    

3.项目实践

3.1需求

OpenHarmony——JS API 之下载-鸿蒙开发者社区

如上图所示,本次需求 有 安装,更新(两者均需单次下载)以及 一键升级(为批量下载),安装下载又分为几个阶段:分别为等待安装,正在验证,正在安装和进度显示,如下图:

OpenHarmony——JS API 之下载-鸿蒙开发者社区

3.2实现方式

3.2.1 hml 界面采用 按钮 和 div 定位的方式布局。如下图
<div class="btn-box">
    <button class="btn"
            @click="clickBtn(item,index)">{{ item.btnText }}
    </button>

    <div class="btn-bg"
         style="width :{{item.process}}%;"
         if="{{ item.state == 'download' || item.state == 'upgradeable' }}"
            >
    </div>
</div>

将div 覆盖到按钮上,让当前下载进度和 div的宽度绑定,下载过程中就会展现 具体的下载进度,从而慢慢填满按钮。

3.2.2 js 实现逻辑

(1) 一键升级

遍历当前页面应用列表,查找 state == “upgradeable” 的应用,将其下标 push进 待安装数据 ,将其状态改为 待安装,按钮文本改为 待安装

如果当前没有正在下载安装的应用,将hasInstalling赋值为true,执行按顺序下载 方法。如下示例

upgrade() {
    this.pageStoreArr.forEach((item, i) => {
        if (item.state == "upgradeable") {
            this.waitingInstsllData.push(i);
            this.pageStoreArr[i].btnText = this.$t("strings.WaitingForInstall");
            this.pageStoreArr[i].state = "waitingInstsll";
        }
    })
    if(!this.hasInstalling && this.pageStoreArr.length>0){//没有正在执行的安装任务
        this.hasInstalling =true;
        this.orderInstallApp();
    }
 },

(2)按顺序下载

​ 将当前待安装数据的第一个赋值给 正在下载下标,获取当前需要下载的应用下载地址,如果待安装数据length为0,将hasInstalling赋值为false

//按点击顺序下载
orderInstallApp() {
    this.installIndex=this.waitingInstsllData[0];
    this.getAppDownloadUrl(this.pageStoreArr[this.installIndex].appID);
    if(this.waitingInstsllData.length==0){
        this.hasInstalling=false;
    }
},

(3)下载

调用下载 api, 进行下载进度监听,再监听回调中,处理当前正在操作的按钮状态以及安装应用

//下载
downloadApp(url) {
   request.download({ url: url }, (err, data)=> {
       if (err) {
           console.error('Fail to request download. Cause:' + err);
           return;
       }
       let downloadTask = data;
       downloadTask.on('progress', this.download_callback);
   });
},

(4)下载进度监听回调

在回调函数中有两个 入参,当前下载大小,和应用总大小,用两者比值在界面显示下载进度,将当前按钮 state = “install”,下载完毕后,将状态改为 正在验证,随后开始安装 应用,安装完毕后,继续执行 遍历下载方法,如下示例:

download_callback(receivedSize, totalSize) {
    console.info("下载那个:"+this.installIndex)
        let percent=(receivedSize / totalSize).toFixed(2) * 100;
        console.info("下载 download receivedSize:" + receivedSize + " totalSize:" + totalSize +"percent:" +percent);
        this.pageStoreArr[this.installIndex].process= percent;
        this.pageStoreArr[this.installIndex].btnText = percent + "%";
        this.pageStoreArr[this.installIndex].state = "install";
    if (percent == 100) {
        setTimeout(() => {
            console.info('Download task completed.');
            this.pageStoreArr[this.installIndex].btnText = this.$t("strings.validating");
        }, 1000)
        setTimeout(() => {//模拟安装
            let filePaths = "internal://cache/app/d875d3fc-85d5-42df-b12a-fcfc8f964107.hap";
            //this.installApp(filePaths)//安装app
            this.pageStoreArr[this.installIndex].btnText = this.$t("strings.installing")
        }, 5000)

        setTimeout(() => {//模拟安装结束
            this.pageStoreArr[this.installIndex].state = "openable";
            this.pageStoreArr[this.installIndex].btnText=this.$t("strings.open")
            this.waitingInstsllData.shift();
            if(this.pageStoreArr.length>0){
                this.orderInstallApp();
            }
        }, 15000)
    }
},

​ (5)单次安装

​ 如果当前应用为未安装或者待更新状态,点击按钮,将其下标push进 待安装数据数组,将其状态改为待安装,如果当前没有下载安装任务,且待安装数据不为空,执行按顺序下载方法,否则,将其按钮文字改为等待安装,应用等待下载安装。代码如下:

clickBtn(data, index) {
    if (data.state == 'download' || data.state == 'upgradeable') {//待安装,待更新
        this.waitingInstsllData.push(index);
        this.pageStoreArr[index].state = "waitingInstsll";
        if (!this.hasInstalling && this.pageStoreArr.length>0) {
            this.hasInstalling =true;
            this.orderInstallApp();
        } else {
            this.pageStoreArr[index].btnText = this.$t("strings.WaitingForInstall");
        }
    } else if (data.state == 'openable') {//已经安装,且最新
    }
},

因为条件所限,安装只能在真机上进行,这边暂时采用模拟安装来执行按顺续下载。

<video src=“img/%E6%8C%89%E9%A1%BA%E5%BA%8F%E4%B8%8B%E8%BD%BD.mp4”></video>

以上即为本次分享的全部内容,如果不足之后,欢迎一起研究探讨。

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-12-14 17:43:24修改
4
收藏 4
回复
举报
3条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢老师对JS API下载进行梳理,清晰多了。

回复
2022-4-21 14:42:19
LL-Siler
LL-Siler

666

1
回复
2022-4-21 15:01:41
Ge
Ge

666666

回复
2022-4-21 17:22:42
回复
    相关推荐