问题描述

上次讲解了通过云存储获取图片url加载云存储的图片,在通过Image组件加载云存储的图片时,通常会经历四个关键阶段:组件创建、图片资源下载、图片解码和刷新。当加载的图片资源过大时,Image组件会在图片数据下载和解码完成后才刷新图片。这一过程中,由于图片下载较耗时,未成功加载的图片常常表现为空白或占位图(一般为白色或淡色),这可能引发“Image 白块”现象。

情景假设

假如现在我们在AGC云存储存储了一组图片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在culture/papercutting的路径下存储了一些关于剪纸的图片,现在,我们要是用bucket.uploadFile接口将图片从云端下载,并缓存到本地沙箱路径context.cacheDir目录

第一步,定义图片路径数组

const ImageList: string[] = [
  'culture/papercutting/paper1.jpg',
  'culture/papercutting/paper2.jpg',
  'culture/papercutting/paper3.jpg',
  'culture/papercutting/paper4.jpeg',
  'culture/papercutting/paper5.jpeg',
  'culture/papercutting/paper6.jpeg'
];

第二步,改造官网案例

官网云存储下载云侧文件至本地
testUtil.ets

import { cloudStorage } from "@kit.CloudFoundationKit";
import { common } from "@kit.AbilityKit";
import { BusinessError, request } from "@kit.BasicServicesKit";
import { fileIo as fs, } from '@kit.CoreFileKit';
 
let storageBucket: cloudStorage.StorageBucket = cloudStorage.bucket();
 
let context = getContext(this) as common.UIAbilityContext;
 
let cacheDir: string = context.cacheDir
 
@Component
export struct testPage {
  build() {
  }
}
 
export async function downloadImageListTest(Paths: string[]) {
  for (const item of Paths) {
    if (fs.accessSync(cacheDir + '/' + item)) {
      console.log(item + '已经存在')
    } else {
 
      downloadImage(item)
      console.log('downloadImage2正在下载' + item)
    }
 
  }
}
 
 
//下载云侧文件至本地
export async function downloadImage(path: string) {
  // 获取云存储默认实例中fileName文件,保存至本地
  storageBucket.downloadFile(getContext(context), {
    localPath: path, // 本地文件路径, 下载成功后,文件将会保存在context.cacheDir目录
    cloudPath: path // 云侧文件路径
  }).then((task: request.agent.Task) => {
    task.on('completed', (progress) => {
      console.info(`on completed ${JSON.stringify(progress)} `);
    });
    task.on('failed', (progress) => {
      console.error(`on failed ${JSON.stringify(progress)} `);
    });
    task.on('response', (response) => {
      console.info(`on response ${JSON.stringify(response)} `);
    });
 
    task.start((err: BusinessError) => {
      if (err) {
        console.error(`Failed to start the downloadFile task, Code: ${err.code}, message: ${err.message}`);
      } else {
        console.info(`Succeeded in starting a downloadFile task. result: ${task.tid}`);
      }
    });
  }).catch((err: BusinessError) => {
    console.error(`downloadFile failed, Code: ${err.code}, message: ${err.message}`);
  });
}

初始化变量:

storageBucket:代表云存储的桶实例。
context:UIAbilityContext上下文对象,用于获取应用环境信息。
cacheDir:表示应用缓存目录的字符串路径。
开始下载:当调用 downloadImageListTest(Paths) 时,它会遍历传入的路径列表 Paths,对于每一个路径,首先检查该路径对应的文件是否已经在本地缓存中存在。如果文件已存在,则跳过下载;否则,它会调用 downloadIamge(path) 来开始下载过程。在 downloadIamge 中,通过 storageBucket.downloadFile 发起一个下载请求。这个请求是一个异步操作,它不会阻塞当前线程。一旦下载任务创建成功,它会监听并响应下载的不同状态(如完成、失败、响应)。

第三步,在主页面中调用downloadImageListTest函数

import { BuilderNameConstants, RouterModule } from 'routermodule';
import { common } from '@kit.AbilityKit';
import { LogUtil } from 'utils/src/main/ets/puraUtils/LogUtil';
import fs, { ListFileOptions } from '@ohos.file.fs';
import { fileUri } from '@kit.CoreFileKit';
import { downloadImageListTest } from '../common/util/testUtil';
 
let context = getContext(this) as common.UIAbilityContext;
let cacheDir: string = context.cacheDir
 
const ImageList: string[] = [
  'culture/papercutting/paper1.jpg',
  'culture/papercutting/paper2.jpg',
  'culture/papercutting/paper3.jpg',
  'culture/papercutting/paper4.jpeg',
  'culture/papercutting/paper5.jpeg',
  'culture/papercutting/paper6.jpeg'
];
 
export function getPath(str: string | undefined): string {
  return fileUri.getUriFromPath(cacheDir + '/' + str)
}
 
function listFileSync(path: string, options?: ListFileOptions): string[] {
  return fs.listFileSync(path, options);
}
 
@Component
 struct testPage {
  aboutToAppear(): void {
    downloadImageListTest(ImageList)
  }
 
  build() {
      Column() {
 
        Button('打印')
          .onClick(() => {
            LogUtil.debug('cacheDir:' + cacheDir)
            LogUtil.print(listFileSync(cacheDir))
            LogUtil.print(listFileSync(cacheDir + "/culture"))
            LogUtil.print(listFileSync(cacheDir + "/culture/papercutting"))
          })
 
        ForEach(ImageList, (item: string) => {
          Image(getPath(item))
            .width(100)
        })
      }
 
    
  }
}

在aboutToAppear()提前下载图片到端侧

如果这时候我们打印日志信息会发现图片已经下载好了
cacheDir目录下存在culture目录,culture目录下存在papercutting目录,papercutting目录则是我们下载要的图片。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第四步,调用图片路径进行Image渲染

我们不难发现cacheDir +“/”+path 就是图片在本地的路径了,但是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据官方文档提示,需要对图片沙箱路径进行转换,才能使用Image渲染,所以别忘了使用
function getPath(str: string | undefined): string { return fileUri.getUriFromPath(cacheDir + ‘/’ + str) } 函数进行转换

注意事项

在涉及文件操作的时候,有的目录以/结尾,有的则不会,如果发生问题,建议打印路径查看是否正确,以至于加上 “/” 或者去除

运行结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关于沙箱路径

(HarmonyOS)为了确保应用的安全性和隐私保护,采用了应用沙箱机制。这一机制为每个应用创建了一个独立的、受保护的运行环境,使得应用只能访问自己被授权的资源和数据,而无法直接访问其他应用的数据或系统的关键部分。这不仅增强了系统的安全性,也提高了用户数据的保密性。在鸿蒙中,应用沙箱路径是指从应用视角看到的文件系统路径,这些路径经过了映射,与实际物理路径并不完全一致。这意味着,应用所见的路径是经过权限隔离和路径挂载隔离后的虚拟路径,它们屏蔽了真实物理路径的细节。我们在上边打印的

LogUtil.debug(‘cacheDir:’ + cacheDir)
路径实际上是一个虚拟路径

关于context

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系统可能会自动清理缓存目录中的文件,因此不要在cacheDir目录中存储重要的、不可恢复的数据,除了cacheDir还可以在其他目录下放置文件

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
1

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐