Issue
在 React-Native (0.43) 应用程序中,我们使用一个组件,该组件使用 SectionList 来渲染按天排序的照片。每个部分可以包含多个图像。照片是使用反应本机图像作物选择器库并上传到后端,或者在没有可用互联网连接的情况下在本地排队,以 base64 格式编码。图像分辨率设置为 800x800 像素(图像其他用途的要求)。在内存较低的手机上,渲染约 20 张图像将导致应用程序因内存不足而崩溃。此问题只能在低端 Android 手机上重现,但我预计这是内存不足的问题,与操作系统无关。为了解决这个问题,需要生成缩略图来测试是否是这种情况。与这些缩略图的生成时间无关(在发送到服务器之前或在加载组件之前即时生成)。下面的代码在 iOS 上运行良好,但在 Android 上会抛出错误:未知协议:数据它来自于ImageEditor.cropImage()功能。
主 .js 文件的片段
//The mergeReduxWithMeteor function takes care of merging the redux state,
//containing images not yet uploaded to the server,
//and the Meteor data as received by the server.
//No issues here...
helpers.mergeReduxWithMeteor(props.photoStore, props.SynergySummaryReady ? props.SynergyData : [])
//The imageHelper.compressPhoto does the actual compression
//No issues with the promise chain as is.
.then((data) => {
return Promise.all(data.map(imageHelper.compressPhoto))
})
// The remaining functions take care of the formatting for the SectionList.
// No issues here either... :)
.then((data) => {
return helpers.clusterDataByDay(data)
})
//We populate the resulting data in the state that is used for the SectionList
.then((data) => {
this.setState({NotHorusData: data})
})
.catch((error) => console.error(error))
imageHelper.compressphoto()
export function compressPhoto(photo) {
return new Promise((resolve, reject) => {
let imageSize = {
offset: {
x: 0,
y: 0
},
size: {
width: IMAGE_SIZE,
height: IMAGE_SIZE
},
displaySize: {
width: IMAGE_TARGET_SIZE,
height: IMAGE_TARGET_SIZE,
},
resizeMode: 'contain'
}
ImageEditor.cropImage(`data:image/jpeg;base64,${photo.data.userPhoto}`, imageSize, (imageURI) => {
ImageStore.getBase64ForTag(imageURI, (base64Data) => {
resolve({
...photo,
data: {
...photo.data,
userPhoto: base64Data,
}
})
}, (error) => reject(error))
}, (error) => reject(error))
})
}
方法一:修复Android上的数据协议问题
Github 上的问题来自 RN 解决了同样的问题,但没有提供解决方案。
方法2:在Android上通过提供uri来绕过数据协议问题
尽管由于增加的通信/延迟而不太有利,但另一种方法是通过提供 ImageStore 提供的临时 URI 来避免数据协议问题。请参阅下面针对 Android 的改编代码。
if(Platform.OS === 'android'){
ImageStore.addImageFromBase64(`data:image/jpeg;base64,${photo.data.userPhoto}`, (tempURI) => {
ImageEditor.cropImage(tempURI, imageSize, (imageURI) => {
ImageStore.getBase64ForTag(imageURI, (base64Data) => {
ImageStore.removeImageForTag(tempURI)
resolve({
...photo,
data: {
...photo.data,
userPhoto: base64Data,
}
})
}, (error) => reject(error))
}, (error) => reject(error))
}, (error) => reject(error))
}
很遗憾ImageStore.addImageFromBase64Android 上无法识别。
有谁有任何经验图片编辑器 and 图片库在 Android 上,这在这种情况下可能会有帮助吗?也欢迎任何其他方法!