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%')
  }
}

【总结】

  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. 检查媒体扫描服务:HarmonyOS中,媒体图库的刷新依赖于系统的媒体扫描服务。确认媒体扫描服务是否正常运行,是否对新文件进行了扫描。

  4. 查看日志信息:通过hilog工具查看系统日志,检查是否有与媒体扫描相关的错误或警告信息,帮助定位问题。

  5. 测试其他应用:使用其他应用保存图片,观察媒体图库是否能正常刷新,排除是否为SaveButton或当前应用的问题。

  6. 检查权限:确认应用是否有写入外部存储和访问媒体图库的权限,权限不足可能导致文件保存后媒体图库无法刷新。

  7. 更新系统版本:确保系统和应用版本为最新,旧版本可能存在已知问题。

  8. 参考官方文档:查阅HarmonyOS开发者文档,了解媒体图库刷新的相关机制和API使用是否正确。

通过以上步骤,可以逐步定位问题所在,确定是路径、权限、服务还是应用本身的问题。

回到顶部