fix: memory leaks around image picking/saving to device

This commit is contained in:
Nathan Walker
2022-02-26 10:15:12 -08:00
parent 40c5984966
commit 7dcfecffab
5 changed files with 75 additions and 7 deletions

View File

@ -8,7 +8,8 @@
},
"dependencies": {
"@nativescript/core": "file:../../packages/core",
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core"
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core",
"@nativescript/imagepicker": "^1.0.6"
},
"devDependencies": {
"@nativescript/android": "alpha",

View File

@ -10,6 +10,7 @@
<Button text="box-shadow" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="css-playground" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="image-async" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="image-handling" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="list-page" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="root-layout" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />
<Button text="switch" tap="{{ viewDemo }}" class="btn btn-primary btn-view-demo" />

View File

@ -0,0 +1,54 @@
import { Observable, EventData, Page, ImageSource, knownFolders, path } from '@nativescript/core';
import { create, ImagePickerMediaType } from '@nativescript/imagepicker';
let page: Page;
export function navigatingTo(args: EventData) {
page = <Page>args.object;
page.bindingContext = new DemoModel();
}
export class DemoModel extends Observable {
addingPhoto = false;
pickImage() {
const context = create({
mode: 'single',
mediaType: ImagePickerMediaType.Image,
});
context
.authorize()
.then(() => {
return context.present();
})
.then((selection) => {
const imageAsset = selection.length > 0 ? selection[0] : null;
if (imageAsset) {
this.addingPhoto = true;
ImageSource.fromAsset(imageAsset).then(
(savedImage) => {
const folder = knownFolders.documents();
const filePath = path.join(folder.path, `assets-${Date.now()}.jpg`);
console.log('filePath:', filePath);
const saved = savedImage.saveToFile(filePath, 'jpg');
if (saved) {
console.log(`file saved:`, filePath);
} else {
console.log('file not saved!');
}
this.addingPhoto = false;
},
(err) => {
this.addingPhoto = false;
}
);
}
})
.catch((e) => {
console.log(e);
});
}
}

View File

@ -0,0 +1,13 @@
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
<Page.actionBar>
<ActionBar title="Permissions" icon="" class="action-bar">
</ActionBar>
</Page.actionBar>
<StackLayout class="p-20">
<Label text="Test Memory leaks with image picking and saving to device. Best to profile from platform IDE like Xcode." textWrap="true" />
<Button text="Pick and Save Image" tap="{{ pickImage }}" />
</StackLayout>
</Page>

View File

@ -1,5 +1,6 @@
import { ImageAssetBase, getRequestedImageSize } from './image-asset-common';
import { path as fsPath, knownFolders } from '../file-system';
import { queueGC } from '../utils';
export * from './image-asset-common';
@ -40,10 +41,8 @@ export class ImageAsset extends ImageAssetBase {
const requestedSize = getRequestedImageSize({ width: srcWidth, height: srcHeight }, this.options);
if (this.nativeImage) {
const newSize = CGSizeMake(requestedSize.width, requestedSize.height);
const resizedImage = this.scaleImage(this.nativeImage, newSize);
callback(resizedImage, null);
callback(this.scaleImage(this.nativeImage, CGSizeMake(requestedSize.width, requestedSize.height)), null);
queueGC();
return;
}
@ -53,11 +52,11 @@ export class ImageAsset extends ImageAssetBase {
PHImageManager.defaultManager().requestImageForAssetTargetSizeContentModeOptionsResultHandler(this.ios, requestedSize, PHImageContentMode.AspectFit, imageRequestOptions, (image, imageResultInfo) => {
if (image) {
const resultImage = this.scaleImage(image, requestedSize);
callback(resultImage, null);
callback(this.scaleImage(image, requestedSize), null);
} else {
callback(null, imageResultInfo.valueForKey(PHImageErrorKey));
}
queueGC();
});
}