Android设备使用Expo Image Picker选50MP相机拍照时崩溃
Android下Expo ImagePicker 50MP 3:4配置导致应用崩溃重启的解决方案
问题概述
- 调用expo-image-picker的相机功能,当系统相机设置为3:4比例+50MP分辨率时,拍完照片点击OK后应用随机崩溃或重启
- 新建仅含拍照按钮的最小化Expo项目仍复现该问题,且仅在50MP配置下触发
- JS控制台无报错信息,Android Studio日志显示
NullPointerException,核心错误为Attempt to invoke virtual method 'void com.facebook.react.ReactDelegate.onActivityResult(...)' on a null object reference
报错根源分析
从Android日志可以看出,崩溃的核心原因是ReactActivity被系统回收:50MP分辨率的图片体积极大(单张可达几十MB),会瞬间占用大量内存,触发Android系统的低内存回收机制,将后台的ReactActivity销毁,最终在回调相机结果时因ReactDelegate对象为空抛出空指针异常。
可行解决方案
1. 强制限制图片分辨率
通过launchCameraAsync的maxWidth和maxHeight参数,强制将输出图片的分辨率限制在合理范围,同时保持3:4的比例。例如将分辨率限制为4000x3000(约12MP),既能满足大部分场景需求,又能大幅降低内存占用。
2. 进一步降低图片质量
尝试将quality值调至更低(如0.05),进一步压缩图片体积,减少内存压力。
3. 启用Android大内存堆
在app.json中配置Android的largeHeap为true,让应用获得更多可用内存空间,降低被系统回收的概率。
4. 升级Expo依赖
将expo和expo-image-picker升级至最新稳定版本,官方可能已修复该高分辨率场景下的内存回收问题。
修改后的代码示例
App.js(添加分辨率限制)
import * as ImagePicker from 'expo-image-picker'; import React, { useState } from 'react'; import { Button, View } from 'react-native'; export default function App() { const [image, setImage] = useState(null); const takePicture = async () => { const c = await ImagePicker.requestCameraPermissionsAsync(); if (c.status === "granted") { let result = await ImagePicker.launchCameraAsync({ aspect: [4, 3], quality: 0.05, maxWidth: 4000, maxHeight: 3000, // 保持3:4比例,对应约12MP分辨率 }); if (!result.canceled) { setImage(result.assets[0].uri); } } }; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="Take a picture " onPress={takePicture} /> </View> ); }
app.json(启用largeHeap)
{ "expo": { "name": "camera-test", "android": { "largeHeap": true } } }
验证步骤
- 修改代码后,执行
expo prebuild --clean清理旧构建文件 - 重新运行
expo start --android安装测试包 - 在系统相机设置中切换至50MP 3:4模式,多次拍摄不同场景测试,确认是否仍出现崩溃
内容的提问来源于stack exchange,提问作者Andrews
相关产品推荐
相关产品推荐

