You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:54:51