React Native Vision Camera useFrameProcessor 随机崩溃问题求助
解决react-native-vision-camera useFrameProcessor随机崩溃问题(Image is already closed)
问题原因
崩溃的核心原因是:在Frame Processor的worklet函数中直接打印整个Frame对象,或者在worklet执行完成后访问Frame的属性。Vision Camera的Frame对象对应原生层的图片资源,worklet执行完毕后会被立即回收释放,当JS尝试访问已经被关闭的Image属性(比如width)时,就会抛出IllegalStateException: Image is already closed错误。
解决方法
- 禁止直接打印整个Frame对象:改为只提取你需要的属性,并且在worklet内部立即读取这些属性的值,避免后续访问已释放的资源。
- 同步读取Frame属性:如果需要使用Frame的信息,必须在worklet执行期间完成数据提取,不要保留对Frame对象的引用。
- 验证依赖兼容性:你当前的依赖版本(react-native-vision-camera v3.0.0 + react-native-worklets-core v0.2.0)是兼容的,若问题仍存在,可尝试升级到两个库的最新稳定版。
修改后的代码示例
import React, {useEffect, useRef, useState} from 'react'; import {ActivityIndicator, SafeAreaView, StyleSheet} from 'react-native'; import { Camera, Frame, useCameraDevices, useFrameProcessor, } from 'react-native-vision-camera'; function App(): JSX.Element { const [cameraAccess, setCameraAccess] = useState(false); const camera = useRef(null); const askPermission = async () => { try { const getPermission = await Camera.getCameraPermissionStatus(); if (getPermission === 'denied') { const reqPrmission = await Camera.requestCameraPermission(); if (reqPrmission === 'granted') { setCameraAccess(true); console.log('Access granted'); } } else if (getPermission === 'granted') { // 补充:已授权时直接更新状态 setCameraAccess(true); } } catch (e) { console.log(e); } }; useEffect(() => { console.log('useEffect is called'); askPermission(); }, []); const devices = useCameraDevices(); const device = devices.back; const frameProcessor = useFrameProcessor((frame: Frame): any => { 'worklet'; // 只提取需要的属性并立即打印,避免访问已释放的Frame对象 const frameInfo = { width: frame.width, height: frame.height, timestamp: frame.timestamp }; console.log('Frame info:', frameInfo); }, []); if (device == null && !cameraAccess) { console.log('camera not found'); return <ActivityIndicator style={styles.sectionContainer} size={'large'} />; } return ( <SafeAreaView style={styles.sectionContainer}> {device != null && ( <Camera style={StyleSheet.absoluteFill} ref={camera} device={device} isActive={true} frameProcessorFps={5} frameProcessor={frameProcessor} /> )} </SafeAreaView> ); } const styles = StyleSheet.create({ sectionContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'white', }, camera: { flex: 10, width: '100%', }, }); export default App;
额外优化点
- 补充了权限已授权时的状态更新逻辑,避免授权后界面未切换的问题
- 渲染Camera组件前增加device非空判断,防止空值渲染引发的异常
内容的提问来源于stack exchange,提问作者Chay.code
相关产品推荐
相关产品推荐

