HarmonyOS 鸿蒙Next SaveButton保存图片 媒体图库未实时刷新问题如何定位

HarmonyOS 鸿蒙Next SaveButton保存图片 媒体图库未实时刷新问题如何定位

【问题现象】

使用SaveButton保存图片时,媒库不能实时刷新展示新图片,必须将App关闭才能在相册中看到图片。

【背景知识】

1、SaveButton组件

SaveButton组件允许用户通过点击按钮临时获取存储权限,无需额外的编写权限申请代码。当用户点击该控件时,应用会获得10秒内单次访问媒体库特权接口的授权。这适用于任何需要将文件保存到媒体库的应用场景,例如保存图片或视频等。

2、图片处理服务

  • Image Kit是一个用于图片处理和显示的服务,它提供了一系列的功能和工具,帮助开发者在鸿蒙应用中高效地处理和展示图片,主要功能包括图片解码、图片处理、图片编码;
  • ImagePacker主要用于图片编码,图片编码指将PixelMap编码成不同格式的存档图片,当前支持打包为JPEG、WebP、png和 HEIF(不同硬件设备支持情况不同) 格式,用于后续处理,如保存、传输等,涉及的api为@ohos.multimedia.image(图片处理)
  • packToFile:指定打包参数,将PixelMap图片源编码后直接打包进文件,需要注意的是:使用packToFile方法,需要调用imagePacker.release主动释放imagePacker,打开图库时才能看到新存入的图片。

【定位思路】

媒体库需要在全部file文件的fd都close后才会刷新图库。如果使用packToFile方法,需要调用release主动释放ImagePacker,此时imagePacker内的fd也会close,媒体库才会刷新,打开图库才能看到新存入的图片。

【解决方案】

ArkTS有内存回收机制,ImagePacker对象不调用release方法,内存最终也会由系统统一释放。但图片使用的内存往往较大,为尽快释放内存,建议应用在使用完成后主动调用release方法提前释放内存,代码示例如下:

(1)导入必要模块:

import { resourceManager } from '@kit.LocalizationKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';
import { promptAction } from '@kit.ArkUI';
import { fileIo } from '@kit.CoreFileKit';

(2)关键类SavePixelMapToAlbum及函数:

[@Entry](/user/Entry)
[@Component](/user/Component)
export struct SavePixelMapToAlbum {
  [@State](/user/State) saveButtonOptions: SaveButtonOptions = {
    icon: SaveIconStyle.FULL_FILLED,
    text: SaveDescription.SAVE,
    buttonType: ButtonType.Capsule
  };
  [@State](/user/State) pixel: image.PixelMap | undefined = undefined;
  [@State](/user/State) albumPath: string = '';
  [@State](/user/State) photoSize: number = 0;
  private context: Context = getContext(this);

async aboutToAppear() { const resourceMgr: resourceManager.ResourceManager = this.context.resourceManager; const fileData: Uint8Array = await resourceMgr.getMediaContent($r(‘app.media.app_icon’).id); let buffer = new Uint8Array(fileData).buffer as object as ArrayBuffer; let imageResource = image.createImageSource(buffer); let opts: image.DecodingOptions = { editable: true }; this.pixel = await imageResource.createPixelMap(opts); }

async saveSnapshot() { try { const context = getContext(this); let helper = photoAccessHelper.getPhotoAccessHelper(context); let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, ‘png’) let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE) // 写入文件 const imagePackerApi: image.ImagePacker = image.createImagePacker(); let packOpts: image.PackingOption = { format: ‘image/png’, quality: 100 }; imagePackerApi.packToFile(this.pixel, file.fd, packOpts).finally(() => { //指定打包参数,将PixelMap图片源编码后直接打包进文件 fileIo.close(file.fd).finally(() => { promptAction.showToast({ message: ‘图片保存成功!’ }) imagePackerApi.release() //主动调用release方法释放内存 }) }) } catch (error) { } } build() { Column() { Image(this.pixel) .objectFit(ImageFit.None) .height(‘30%’) SaveButton(this.saveButtonOptions) //点击保存图片 .onClick(async (event, result: SaveButtonOnClickResult) => { if (result === SaveButtonOnClickResult.SUCCESS) { this.saveSnapshot() } }) } .justifyContent(FlexAlign.Start) .height(‘100%’) .width(‘100%’) } }

【总结】

(1)ArkTS有内存自动回收机制,数据类型分为两类,简单类型和引用类型。简单类型内容直接保存在栈(Stack)中,由操作系统自动分配和释放。引用类型保存在堆(heap)中,需要引擎进行手动释放。GC就是针对堆空间的内存自动回收的管理机制。

(2)在开发过程中,碰到内存使用较大的业务场景,需要主动尽快释放内存,有效地进行内存管理和避免内存泄漏,提高应用的性能和稳定性,例如:

  • 使用on注册回调,需要及时进行off释放
  • 注册媒体查询,需要解注册
  • 自定义弹窗即将析构销毁时将dialogControlle置空

更多关于HarmonyOS 鸿蒙Next SaveButton保存图片 媒体图库未实时刷新问题如何定位的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next SaveButton保存图片 媒体图库未实时刷新问题如何定位的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对HarmonyOS 鸿蒙Next中SaveButton保存图片后媒体图库未实时刷新的问题,以下是一些定位步骤:

  1. 检查权限

    • 确认应用已正确申请并获得了存储权限,因为未获得相应权限可能导致文件无法写入。
  2. 验证保存路径

    • 确保图片被保存在系统认可的图片存储目录下,否则系统可能无法识别新保存的图片。
  3. 监听相册变更

    • 尝试使用系统提供的广播或内容观察者机制,监听相册内容的变更,从而触发相册的刷新。
  4. 调用媒体扫描接口

    • 在保存图片后,调用系统的媒体扫描接口(如MediaScannerConnection.scanFile),确保系统能够立即识别新保存的图片。
  5. 检查代码逻辑

    • 仔细检查SaveButton的点击事件处理逻辑,确保图片保存操作正确无误,并且在保存后触发了必要的刷新机制。

如果以上步骤均正确无误,但问题依旧存在,可能是由于系统缓存或特定版本的bug导致。此时,可以尝试清除应用缓存或重启设备看是否能解决问题。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部