HarmonyOS 鸿蒙Next中离线下载

HarmonyOS 鸿蒙Next中离线下载

如何实现文件下载存储内容,并实时获取下载进度用于展示,同时保持后台下载功能

9 回复

开发者您好,可参考示例代码中的多文件下载监听,使用request.agent.create创建上传任务,通过on(‘progress’)监听下载进度。由于使用@ohos.request (上传下载)退至后台由系统托管,因此不用申请长时任务权限,也可以保持后台下载。文件保存目录在request.agent.Config的saveas字段中设置,示例中设置为默认的沙箱目录。如果想设置为其他目录,可参考应用文件上传下载,其中有案例设置下载目录为应用文件目录或用户文件目录。

更多关于HarmonyOS 鸿蒙Next中离线下载的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我要下载存储的是接口返回的一个个json数据,每一个json对象包含但不限于{时间,唯一id,几千字的文本内容}等等属性,根据我的选择接口会返回几个到几千个不等的json对象

开发者您好,请问您具体的场景是怎样的,请详细说明。若需要写入沙箱,直接使用fs.open打开或创建文件,使用fs.write写入即可。如果已有接口返回信息,那写入沙箱应展示写入进度,而非下载进度,请说明。

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

你好,可以参考示例代码:

多文件下载监听

你可以看一下这个地方:长时任务

import http from '@ohos.net.http';
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import backgroundTaskManager from '@kit.Ability.BackgroundTaskManager';

// 文件下载工具类
class DownloadUtil {
  // 启动后台长时任务
  private async startBackgroundTask(): Promise<number> {
    try {
      const bgTaskId = await backgroundTaskManager.startBackgroundRunning({
        backgroundMode: backgroundTaskManager.BackgroundMode.DATA_TRANSFER
      });
      return bgTaskId;
    } catch (error) {
      console.error(`后台任务启动失败: ${error.code}, ${error.message}`);
      return -1;
    }
  }

  // 下载文件主逻辑
  public async downloadFile(url: string, fileName: string) {
    const context = getContext() as common.UIAbilityContext;
    const savePath = `${context.filesDir}/${fileName}`;
    let bgTaskId = -1;
    
    // 1. 启动后台任务
    bgTaskId = await this.startBackgroundTask();
    
    // 2. 创建HTTP请求
    const httpRequest = http.createHttp();
    const fileStream = fs.createStreamSync(savePath, "w+");

    // 3. 进度监听回调
    httpRequest.on('dataReceiveProgress', (progressData: http.DataReceiveProgressInfo) => {
      const percent = Math.round((progressData.receiveSize / progressData.totalSize) * 100);
      // 此处更新UI进度(示例)
      console.info(`下载进度: ${percent}%`);
    });
    
    // 4. 数据接收处理
    httpRequest.on('dataReceive', (buffer: ArrayBuffer) => {
      fileStream.writeSync(buffer);
    });

    try {
      // 5. 发起下载请求
      await httpRequest.request(url, {
        method: http.RequestMethod.GET,
        readTimeout: 60000 * 30 // 延长超时时间
      });
      
      // 6. 下载完成处理
      fileStream.flushSync();
      fileStream.closeSync();
    } finally {
      // 7. 停止后台任务
      if (bgTaskId !== -1) {
        backgroundTaskManager.stopBackgroundRunning(bgTaskId);
      }
    }
  }
}
  1. 后台下载保障

    • 使用BackgroundMode.DATA_TRANSFER长时任务类型
    • 通过startBackgroundRunning()申请后台权限
    • 下载完成后调用stopBackgroundRunning()释放资源
    • 参考:1应用前台切后台下载需与长时任务协同
  2. 实时进度监控

    • 监听dataReceiveProgress事件
    • 通过receiveSize/totalSize计算百分比
    • 使用OnDownloadProgress接口监听进度
  3. 文件存储处理

    • 使用@kit.CoreFileKit文件操作模块
    • 通过createStreamSync()创建文件流
    • 分块写入避免内存溢出(dataReceive事件)

三、配置要求

  1. 权限声明(module.json5)
"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  },
  {
    "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
  }
]
  1. 后台模式声明
"abilities": [
  {
    "backgroundModes": ["dataTransfer"]
  }
]

还可以参考:

RCP下载进度监听

ArkTs实现文件下载

鸿蒙Next的离线下载功能通过分布式数据管理实现,支持无网络环境下应用与数据同步。该功能基于HarmonyOS的分布式软总线技术,允许设备间直接传输数据。开发者可使用DataShare或DistributedDataKit接口进行跨设备数据访问,系统会自动管理数据同步与冲突解决。离线状态下,应用通过本地数据库操作数据,网络恢复后自动同步至其他设备。

在HarmonyOS Next中实现文件下载、进度监控与后台任务,核心是使用@ohos.request@ohos.taskpool模块。以下是关键实现步骤:

1. 下载与存储实现

使用request.downloadFile()接口:

import request from '@ohos.request';
import fs from '@ohos.file.fs';

async function downloadFile(url: string, fileName: string) {
  let downloadConfig: request.DownloadConfig = {
    url: url,
    filePath: getContext().filesDir + '/' + fileName, // 应用沙箱路径
    overwrite: true
  };
  
  let task: request.DownloadTask = await request.downloadFile(getContext(), downloadConfig);
  return task;
}

2. 实时进度获取

通过DownloadTask的订阅机制:

task.on('progress', (receivedSize: number, totalSize: number) => {
  let progress = (receivedSize / totalSize * 100).toFixed(2);
  // 更新UI进度显示
  updateProgress(progress);
});

task.on('complete', () => {
  console.log('下载完成');
});

task.on('fail', (err: BusinessError) => {
  console.error('下载失败:', err.code);
});

3. 后台下载保持

需配置后台任务与持续化存储:

(1)声明后台权限: 在module.json5中添加:

"abilities": [
  {
    "name": "ServiceAbility",
    "srcEntry": "./ets/serviceability/ServiceAbility.ets",
    "backgroundModes": ["dataTransfer"]
  }
]

(2)使用TaskPool保持后台执行

import taskpool from '@ohos.taskpool';

@Concurrent
async function backgroundDownload(url: string, path: string) {
  // 下载逻辑
}

let task: taskpool.Task = new taskpool.Task(backgroundDownload, url, filePath);
taskpool.execute(task);

(3)状态持久化: 使用Preferences存储下载状态:

import preferences from '@ohos.data.preferences';

// 存储进度
let prefs = await preferences.getPreferences(getContext(), 'downloadPrefs');
await prefs.put('progress', progress);
await prefs.flush();

4. 完整示例结构

class DownloadManager {
  private task: request.DownloadTask | null = null;
  
  async startDownload(url: string, fileName: string) {
    // 1. 创建下载任务
    this.task = await request.downloadFile(getContext(), {
      url: url,
      filePath: getContext().filesDir + '/' + fileName
    });
    
    // 2. 订阅进度
    this.task.on('progress', this.handleProgress.bind(this));
    
    // 3. 启动后台任务
    this.runInBackground();
  }
  
  private handleProgress(received: number, total: number) {
    // 更新进度并持久化
    let progress = (received / total * 100);
    this.saveProgress(progress);
  }
  
  private async runInBackground() {
    // TaskPool后台执行
  }
}

关键注意事项:

  • 网络权限需在module.json5中配置ohos.permission.INTERNET
  • 大文件下载建议使用fs.createStream()分片处理
  • 后台任务需合理管理生命周期,避免资源泄漏
  • 应用退到后台时,下载任务会自动转入后台执行队列

这种实现方式能确保下载任务在应用前后台切换时持续执行,同时通过事件订阅机制实时反馈进度。

回到顶部