10. 多线程实现文件下载

两种方式实现多线程下载文件

一. worker 线程

Index.ets 代码

import { MessageEvents, worker } from '@kit.ArkTS';

//创建一个worker子线程
const  download = new worker.ThreadWorker('entry/ets/workers/downloadWorker.ets')

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
 @State pro: number = 0

  //接收子线程传递过来的数据
  aboutToAppear(): void {
   download.onmessage = (e:MessageEvents) => {
     this.pro = e.data.pro
   }
  }
  build() {
    Column() {
      Button('下载文件')
        .onClick((event: ClickEvent) => {
         //多线程下载文件
          //主线程更新
          //主线程给子线程发消息,将dir路径传递给子线程
          download.postMessage({dir:getContext().filesDir})

      })
      Stack(){
        Progress({value:this.pro,total:100,type:ProgressType.Capsule})
          .width('80%')
          .height(20)
          .color(Color.Red)
          .backgroundColor(Color.Gray)
        Text(this.pro + '%')
          .fontColor(Color.White)
          .align(Alignment.Center)

      }
      .width('100%')
      .margin({top:30})
    }
    .height('100%')
    .width('100%')
  }
}

 通过worker模版创建一个worker子线程


/*
 * 通过worker模版创建子线程
 * */

import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import { download } from '../util/httputil';

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;

/**
 * Defines the event handler to be called when the worker thread receives a message sent by the host thread.
 * The event handler is executed in the worker thread.
 *
 * @param e message data
 */
//子线程接收主线程消息
workerPort.onmessage = (e: MessageEvents) => {
  let uri = ''
   //子线程获取不到dir,需要从主线程传过来
  //子线程执行下载操作
  download(uri,e.data.dir,(progress:number)=>{
    //子线程获取到progress后,通过postmessage 传给主线程
    workerPort.postMessage({pro:progress})
  })
}

/**
 * Defines the event handler to be called when the worker receives a message that cannot be deserialized.
 * The event handler is executed in the worker thread.
 *
 * @param e message data
 */
workerPort.onmessageerror = (e: MessageEvents) => {
}

/**
 * Defines the event handler to be called when an exception occurs during worker execution.
 * The event handler is executed in the worker thread.
 *
 * @param e error message
 */
workerPort.onerror = (e: ErrorEvent) => {
}

二. request.download (不支持断点续传)

另外创建一个page

import { request } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct RequestPage  {
  @State message: string = 'Hello World';
  @State pro: number = 0
  config:request.DownloadConfig = {
    url:'',
    background:true
  }

  build() {
    Column() {
      Button('下载文件')
        .onClick((event: ClickEvent) => {
          //多线程下载文件
          //主线程更新
          request.downloadFile(getContext(),this.config).then((task:request.DownloadTask) => {
            task.on("progress",(rs:number,ts:number) => {
              this.pro = Math.ceil(rs*100/ts)
            })
            task.on("complete",()=>{
              this.pro = 100
              promptAction.showToast({message:'下载文件'})
            })
          })


        })
      Stack(){
        Progress({value:this.pro,total:100,type:ProgressType.Capsule})
          .width('80%')
          .height(20)
          .color(Color.Red)
          .backgroundColor(Color.Gray)
        Text(this.pro + '%')
          .fontColor(Color.White)
          .align(Alignment.Center)

      }
      .width('100%')
      .margin({top:30})
    }
    .height('100%')
    .width('100%')
  }
}

三,request.agent.download (支持断点续传)

import { request } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct RequestPage  {
  @State message: string = 'Hello World';
  @State pro: number = 0
  config:request.agent.Config = {
    url:'',
    action:request.agent.Action.DOWNLOAD,
    overwrite:true,
    gauge:true

  }
  @State taskId:string = ''


  async  onPageShow(): Promise<void> {
    let task = await request.agent.create(getContext(), this.config)
    task.on("progress",(progress:request.agent.Progress) =>{
      this.pro = Math.ceil(progress.processed * 100 / progress.sizes[0])
    })
    task.on("completed",() => {
      this.pro = 100
      promptAction.showToast({message:'文件下载完成'})
    })
    this.taskId = task.tid

  }
  build() {
    Column() {
      Button('下载文件')
        .onClick((event: ClickEvent) => {
          //多线程下载文件
          //主线程更新
          //支持断点续传
          request.agent.getTask(getContext(),this.taskId).then((task) => {
            task.start()
          })


        })
        .alignSelf(ItemAlign.Start)
      Button('暂停')
        .onClick((event: ClickEvent) => {
          request.agent.getTask(getContext(),this.taskId).then((task) => {
            task.pause()
          })


        })
        .alignSelf(ItemAlign.Start)
      Button('继续')
        .onClick((event: ClickEvent) => {
          request.agent.getTask(getContext(),this.taskId).then((task) => {
            task.resume()
          })
        })
        .alignSelf(ItemAlign.Start)
      Stack(){
        Progress({value:this.pro,total:100,type:ProgressType.Capsule})
          .width('80%')
          .height(20)
          .color(Color.Red)
          .backgroundColor(Color.Gray)
        Text(this.pro + '%')
          .fontColor(Color.White)
          .align(Alignment.Center)

      }
      .width('100%')
      .margin({top:30})
    }
    .height('100%')
    .width('100%')
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值