React Native图片/文档选择后返回崩溃问题求助
报错日志
E BufferQueueDebug: 无法从'com.apppackage/com.apppackage.MainActivity$_6796#0'读取id信息
01-02 21:03:41.985 1269 3478 E WindowManager: win=Window{43d3d6e u0 com.apppackage/com.apppackage.MainActivity} destroySurfaces: appStopped=true win.mWindowRemovalAllowed=false win.mRemoveOnExit=false win.mViewVisibility=8 caller=com.android.server.wm.ActivityRecord.destroySurfaces:5866 com.android.server.wm.ActivityRecord.destroySurfaces:5847 com.android.server.wm.ActivityRecord.notifyAppStopped:5911 com.android.server.wm.ActivityRecord.activityStopped:6553 com.android.server.wm.ActivityClientController.activityStopped:254 android.app.IActivityClientController$Stub.onTransact:596 com.android.server.wm.ActivityClientController.onTransact:130
01-02 21:03:46.644 6796 6796 E AndroidRuntime: java.lang.RuntimeException: 向Activity {com.apppackage/com.apppackage.MainActivity}传递ResultInfo{who=null, request=41, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:1000000608 flg=0x1 }}结果失败:java.lang.NullPointerException: 尝试调用空对象引用上的接口方法'void com.facebook.react.bridge.Callback.invoke(java.lang.Object[])'
问题现象
- 应用选择图片或文档后点击返回按钮直接崩溃
- 预期行为:选择完成后正常恢复应用运行
环境信息
"react-native": "~0.62.2", buildToolsVersion = "29.0.3" minSdkVersion = 21 compileSdkVersion = 29 targetSdkVersion = 29 ext.kotlin_version = '1.6.0'
问题分析
核心崩溃原因是NullPointerException:处理文件选择结果时,尝试调用一个空的Callback.invoke方法。这说明Activity从后台返回时,原本用于传递选择结果的React Native Callback对象已被释放或未正确持有,导致回调引用为空触发崩溃。
结合RN 0.62.2的生命周期特性,常见触发场景:
- 第三方文件选择库版本与RN 0.62.2不兼容,未正确处理Activity重建时的回调保留
- 自定义文件选择模块中,Callback未通过WeakReference或组件状态持有,在Activity onStop/onDestroy时被回收
- 组件已卸载,但文件选择的结果仍尝试触发回调
解决方案
1. 适配第三方文件选择库版本
如果使用第三方文件选择库(如react-native-image-picker),确认版本支持RN 0.62.2:
- 例如react-native-image-picker需使用
^2.3.4及以上版本(适配RN 0.62+) - 重新安装依赖并同步gradle:
npm install react-native-image-picker@^2.3.4 --save cd android && ./gradlew clean
2. 自定义模块中正确持有Callback
如果是自定义原生文件选择模块,需确保Callback被正确持有:
- 使用
WeakReference包裹Callback,避免内存泄漏的同时保证回调在Activity重建时可被访问 - 在
onActivityResult中先检查WeakReference是否为空,再调用invoke:private WeakReference<Callback> mCallback; // 启动文件选择时保存回调 public void pickFile(Callback callback) { mCallback = new WeakReference<>(callback); // 启动文件选择Intent逻辑 } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (mCallback != null) { Callback callback = mCallback.get(); if (callback != null) { // 处理结果并调用callback.invoke callback.invoke(resultData); mCallback.clear(); } } }
3. 前端侧防止组件卸载后触发回调
在React组件中,通过状态管理控制回调有效性:
- 定义状态变量标记组件是否已挂载
- 在组件生命周期中更新状态,触发文件选择前检查组件状态:
class FilePickerComponent extends Component { constructor(props) { super(props); this.isMounted = false; } componentDidMount() { this.isMounted = true; } componentWillUnmount() { this.isMounted = false; } pickFile = () => { ImagePicker.launchImageLibrary({}, (response) => { if (this.isMounted) { // 处理选择结果 } }); } // ...其他代码 }
4. 检查Activity配置
确保AndroidManifest.xml中MainActivity配置合理:
- 补充必要的
android:configChanges属性,避免屏幕旋转等操作导致Activity重建 - 确认
android:launchMode未设置为会导致Activity重建的模式(如singleInstance)
内容的提问来源于stack exchange,提问作者Nav

