Problem Description
When using the SaveButton to save images, the media library cannot refresh and display new images in real-time. The app must be closed to view the images in the photo album.
Background Knowledge
SaveButton Component
The SaveButton component allows users to temporarily obtain storage permissions by clicking the button, eliminating the need for additional code to request permissions. When the user clicks this control, the application is granted authorization to access the media library's privileged interface for a single time within 10 seconds. This is suitable for any application scenario that requires saving files to the media library, such as saving images or videos.-
Image Processing Service
- Image Kit is a service designed for image processing and display, offering a range of features and tools to assist developers in efficiently handling and showcasing images within HarmonyOS applications. Its primary functions include image decoding, image processing, and image encoding.
- ImagePacker is primarily used for image encoding, which involves converting PixelMap into archive images of different formats. Currently, it supports packaging into JPEG, WebP, PNG, and HEIF formats (with varying support across different hardware devices), for subsequent processes such as saving and transmitting. The relevant API is @ohos.multimedia.image (image processing).
- packToFile: Specifies the packaging parameters to directly encode the PixelMap image source into a file. It is important to note that when using the packToFile method, the imagePacker must be actively released by calling imagePacker.release to ensure that the newly stored images can be viewed when the gallery is opened.
Troubleshooting Process
The media library will only refresh the gallery after all file descriptors (fd) of the file files have been closed. If the packToFile method is used, it is necessary to call release to actively release the ImagePacker. At this point, the fd within the imagePacker will also be closed, and the media library will refresh, allowing the newly stored images to be visible in the gallery.
Solution
ArkTS has a memory reclamation mechanism. Even if the ImagePacker object does not call the release method, the memory will eventually be released by the system. However, the memory used by images is often large. To release memory as soon as possible, it is recommended that the application actively call the release method after use to release memory in advance. The code example is as follows:
(1) Import the necessary modules:
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) Key class SavePixelMapToAlbum and function:
@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)
// Write to file
const imagePackerApi: image.ImagePacker = image.createImagePacker();
let packOpts: image.PackingOption = { format: 'image/png', quality: 100 };
imagePackerApi.packToFile(this.pixel, file.fd, packOpts).finally(() => {
//Specify packaging parameters to encode the PixelMap image source and directly package it into the file.
fileIo.close(file.fd).finally(() => {
promptAction.showToast({ message: ' successfully ' })
imagePackerApi.release() //Proactively call the release method to free up memory.
})
})
} catch (error) {
}
}
build() {
Column() {
Image(this.pixel)
.objectFit(ImageFit.None)
.height('30%')
SaveButton(this.saveButtonOptions)
//Click to save the image.
.onClick(async (event, result: SaveButtonOnClickResult) => {
if (result === SaveButtonOnClickResult.SUCCESS) {
this.saveSnapshot()
}
})
}
.justifyContent(FlexAlign.Start)
.height('100%')
.width('100%')
}
}
Verification Result
(1) ArkTS has an automatic memory garbage collection mechanism. Data types are divided into two categories: simple types and reference types. The content of simple types is directly stored in the stack (Stack), which is automatically allocated and released by the operating system. Reference types are stored in the heap (heap) and require manual release by the engine. GC is the management mechanism for automatic memory recovery in the heap space.
(2) During the development process, when encountering business scenarios with large memory usage, it is necessary to actively release memory as soon as possible, effectively manage memory, avoid memory leaks, and improve the performance and stability of the application.
For example:
- Use on to register callbacks, and promptly use off to release them.
- Register media queries and unregister them when necessary.
- When a custom dialog is about to be destructed, set the dialogController to null.

Top comments (0)