HarmonyOS鸿蒙Next中SaveButton保存图片,媒体图库没有实时刷新的问题如何定位
HarmonyOS鸿蒙Next中SaveButton保存图片,媒体图库没有实时刷新的问题如何定位
【问题现象】
使用SaveButton保存图片时,媒体库不能实时刷新展示新图片,必须将APP关闭才能在相册中看到图片。
【背景知识】
1. SaveButton组件
SaveButton组件允许用户通过点击按钮临时获取存储权限,无需额外的编写权限申请代码。当用户点击该控件时,应用会获得10秒内单次访问媒体库特权接口的授权。这适用于任何需要将文件保存到媒体库的应用场景,例如保存图片或视频等。
2. 图片处理服务
- Image Kit是一个用于图片处理和显示的服务,它提供了一系列的功能和工具,帮助开发者在HarmonyOS应用中高效地处理和展示图片,主要功能包括图片解码、图片处理、图片编码;
- 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
@Component
export struct SavePixelMapToAlbum {
@State saveButtonOptions: SaveButtonOptions = {
icon: SaveIconStyle.FULL_FILLED,
text: SaveDescription.SAVE,
buttonType: ButtonType.Capsule
};
@State pixel: image.PixelMap | undefined = undefined;
@State albumPath: string = '';
@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%')
}
}
【总结】
-
ArkTS有内存自动回收机制,数据类型分为两类,简单类型和引用类型。简单类型内容直接保存在栈(Stack)中,由操作系统自动分配和释放。引用类型保存在堆(heap)中,需要引擎进行手动释放。GC就是针对堆空间的内存自动回收的管理机制。
-
在开发过程中,碰到内存使用较大的业务场景,需要主动尽快释放内存,有效地进行内存管理和避免内存泄漏,提高应用的性能和稳定性,例如:
- 使用on注册回调,需要及时进行off释放。
- 注册媒体查询,需要解注册。
- 自定义弹窗即将析构销毁时将dialogControlle置空。
更多关于HarmonyOS鸿蒙Next中SaveButton保存图片,媒体图库没有实时刷新的问题如何定位的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中SaveButton保存图片,媒体图库没有实时刷新的问题如何定位的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,SaveButton保存图片后媒体图库没有实时刷新的问题
可以通过以下步骤进行定位:
-
检查保存路径:确认图片保存路径是否正确,是否在媒体图库监控的范围内。通常,媒体图库会监控特定目录的新增文件。
-
查看文件系统:通过文件管理器或命令行工具检查图片是否已成功保存到指定路径,确保文件已写入。
-
检查媒体扫描服务:HarmonyOS中,媒体图库的刷新依赖于系统的媒体扫描服务。确认媒体扫描服务是否正常运行,是否对新文件进行了扫描。
-
查看日志信息:通过
hilog
工具查看系统日志,检查是否有与媒体扫描相关的错误或警告信息,帮助定位问题。 -
测试其他应用:使用其他应用保存图片,观察媒体图库是否能正常刷新,排除是否为SaveButton或当前应用的问题。
-
检查权限:确认应用是否有写入外部存储和访问媒体图库的权限,权限不足可能导致文件保存后媒体图库无法刷新。
-
更新系统版本:确保系统和应用版本为最新,旧版本可能存在已知问题。
-
参考官方文档:查阅HarmonyOS开发者文档,了解媒体图库刷新的相关机制和API使用是否正确。
通过以上步骤,可以逐步定位问题所在,确定是路径、权限、服务还是应用本身的问题。