鸿蒙网络编程系列38-Web组件文件下载示例

1. web组件文件下载能力简介

在本系列的第22篇文章,介绍了web组件的文件上传能力,同样的,web组件也具备文件下载能力,鸿蒙API提供了处理web组件下载事件的委托类型WebDownloadDelegate,该类型包括四个下载事件的回调接口:

javascript 复制代码
class WebDownloadDelegate {
//下载开始前通知用户,用户需要在此接口中调用WebDownloadItem.start提供下载路径
onBeforeDownload(callback: Callback<WebDownloadItem>): void

//下载过程中的回调
onDownloadUpdated(callback: Callback<WebDownloadItem>): void

//下载完成后的回调
onDownloadFinish(callback: Callback<WebDownloadItem>): void

//下载失败时的回调
onDownloadFailed(callback: Callback<WebDownloadItem>): void
}

web组件的控制器类WebviewController提供了设置web组件下载事件委托的方法setDownloadDelegate:

javascript 复制代码
setDownloadDelegate(delegate: WebDownloadDelegate): void

web组件在下载状态变化时会自动调用委托中的对应回调函数。

本文将通过一个示例演示web组件的下载能力,通过进度条展示下载进度的变化。

2. web组件文件下载演示

本示例运行后的界面如图所示:

输入要浏览的网页地址,然后单击"加载"按钮加载网页,加载成功后单击要下载文件的超链接即可开始下载,如图所示:

这里我们下载的是哔哩哔哩网站的安卓版客户端,在应用的下载展示了下载的位置和当前的进度以及下载速度。下载完毕的界面如图所示:

这样就完成了web组件的下载功能演示。

3. web组件文件下载示例编写

下面详细介绍创建该示例的步骤。

步骤1:创建Empty Ability项目。

步骤2:在module.json5配置文件加上对权限的声明:

json 复制代码
"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

这里添加了访问互联网的权限。

步骤3:在Index.ets文件里添加如下的代码:

javascript 复制代码
import webview from '@ohos.web.webview';
import web_webview from '@ohos.web.webview'

@Entry
@Component
struct Index {
  @State title: string = "Web组件文件下载示例"
  //下载状态
  @State downloadState: string = ""
  //当前下载速度
  @State downloadSpeed: string = ""
  //下载文件保存位置
  @State downloadPath: string = ""
  //下载进度
  @State downloadProgress: number = 0
  //要加载的网址
  @State webUrl: string = "https://app.bilibili.com/"

  scroller: Scroller = new Scroller()
  controller: web_webview.WebviewController = new web_webview.WebviewController()

  build() {
    Row() {
      Column() {
        Text(this.title)
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .width('100%')
          .textAlign(TextAlign.Center)
          .padding(10)

        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text("网址:")
            .fontSize(14)
            .width(50)
            .flexGrow(0)

          TextInput({ text: this.webUrl })
            .onChange((value) => {
              this.webUrl = value
            })
            .width(110)
            .fontSize(11)
            .flexGrow(1)

          Button("加载")
            .onClick(() => {
              this.controller.loadUrl(this.webUrl);
              this.controller.setDownloadDelegate(this.buildDownloadDelegate())
            })
            .width(60)
            .fontSize(14)
            .flexGrow(0)
        }
        .width('100%')
        .padding(5)

        Scroll(this.scroller) {
          Web({ src: "", controller: this.controller })
            .padding(10)
            .width('100%')
            .textZoomRatio(150)
            .backgroundColor(0xeeeeee)
        }
        .align(Alignment.Top)
        .backgroundColor(0xeeeeee)
        .height(300)
        .flexGrow(1)
        .scrollable(ScrollDirection.Vertical)
        .scrollBar(BarState.On)
        .scrollBarWidth(20)

        Progress({ total: 100, type: ProgressType.Linear, value: this.downloadProgress })
        Text(this.downloadPath)
          .fontSize(11)
          .width('100%')
          .padding(5)
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text(this.downloadState)
            .fontSize(11)
          Divider().vertical(true).height(15).width(10)
          Text(this.downloadSpeed)
            .fontSize(11)
        }
        .width('100%')
        .padding(5)
      }
      .width('100%')
      .justifyContent(FlexAlign.Start)
      .height('100%')
    }
    .height('100%')
  }

  //创建web组件下载状态回调的委托
  buildDownloadDelegate() {
    let downloadDelegate: webview.WebDownloadDelegate = new webview.WebDownloadDelegate();
    //下载前的回调
    downloadDelegate.onBeforeDownload((webDownloadItem: webview.WebDownloadItem) => {
      //下载文件保存位置
      let localFilePath = getContext(this).cacheDir + "/" + webDownloadItem.getSuggestedFileName()
      webDownloadItem.start(localFilePath);
      this.downloadState = "开始下载"
      this.downloadPath = `保存位置:${localFilePath}`
    })

    //下载过程中的通知
    downloadDelegate.onDownloadUpdated((webDownloadItem: webview.WebDownloadItem) => {
      this.downloadState = "正在下载"
      this.downloadProgress = webDownloadItem.getPercentComplete()
      this.downloadSpeed = `当前下载速度:${webDownloadItem.getCurrentSpeed()}比特/秒`
    })

    //下载失败的通知
    downloadDelegate.onDownloadFailed(() => {
      this.downloadState = `下载失败`
    })

    //下载完成的通知
    downloadDelegate.onDownloadFinish(() => {
      this.downloadState = "下载完成"
    })

    return downloadDelegate
  }
}

步骤4:编译运行,可以使用模拟器或者真机。

步骤5:按照本节第2部分"web组件文件下载演示"操作即可。

4. 代码分析

本示例关键点在于构造web组件的下载委托,通过委托的onBeforeDownload回调设置下载文件的保存位置,并通过webDownloadItem的start方法开始下载。

javascript 复制代码
    downloadDelegate.onBeforeDownload((webDownloadItem: webview.WebDownloadItem) => {
      //下载文件保存位置
      let localFilePath = getContext(this).cacheDir + "/" + webDownloadItem.getSuggestedFileName()
      webDownloadItem.start(localFilePath);
      this.downloadState = "开始下载"
      this.downloadPath = `保存位置:${localFilePath}`
    })

(本文作者原创,除非明确授权禁止转载)

本文源码地址:
https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/DownloadInWeb

本系列源码地址:
https://gitee.com/zl3624/harmonyos_network_samples

相关推荐
Mahut10 分钟前
从零构建神经影像可视化库:neuroviz 的架构设计与实现
前端·javascript·github
慧一居士14 分钟前
VueUse 功能介绍使用场景及完整使用示例
前端·vue.js
奇怪的猫15 分钟前
浏览器窗口最小化的时候,setInterval 执行变慢,解决方案
前端·javascript
多租户观察室15 分钟前
工作流新生态:2026年工作流与Coding的重新分工
前端·人工智能·后端·低代码
cmd16 分钟前
别再混淆了!JS类型转换底层:valueOf vs toString vs Symbol.toPrimitive 详解
前端·javascript
Carsene30 分钟前
开源项目文档架构设计:Git Submodule 实现文档与代码的优雅分离
前端·后端
Z思学34 分钟前
promise 有几种状态 async/await 和promise 有什么关系
前端
han_35 分钟前
JavaScript设计模式(四):发布-订阅模式实现与应用
前端·javascript·设计模式
276695829237 分钟前
租车帮(悟空)订单查询算法分析
java·服务器·前端·悟空·悟空app·租车帮·租车帮逆向
__雨夜星辰__1 小时前
TypeScript 入门学习笔记(面向对象 + 常用设计模式)
前端·学习·typescript