天天看點

OpenHarmony——JS API 之下載下傳

作者:吳進濤

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開發技術,歡迎投稿和訂閱,讓我們一起攜手前行共建鴻蒙生态。

想了解更多關于鴻蒙的内容,請通路:

51CTO OpenHarmony技術社群

https://ost.51cto.com/#bkwz

繼續閱讀