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

React Native中Reanimated报错“Reading from _value directly...”解决咨询

解决方案:"Reading from _value directly is only possible on the UI runtime" 错误修复

错误核心原因

  1. SharedValue跨线程操作违规:frameProcessor是运行在Vision Camera专用帧处理线程的worklet,直接在其中修改SharedValue的.value属性(pose.value = poseCopy)违反了Reanimated规则——SharedValue的读写必须在UI线程执行。
  2. UI线程变量在非UI线程访问:dimensions是来自useWindowDimensions()的UI线程状态,直接在非UI线程的frameProcessor中访问存在线程安全问题。

具体修改步骤

1. 补充导入并将屏幕尺寸转为SharedValue

在Reanimated导入中添加runOnUI,并将窗口尺寸转为SharedValue以保证跨线程安全访问:

import Animated, { useSharedValue, useAnimatedProps, runOnUI } from 'react-native-reanimated';

// ...

const App = () => {
  const pose = useSharedValue(defaultPose);
  const dimensions = useWindowDimensions();
  // 将屏幕尺寸转为SharedValue
  const screenDimensions = useSharedValue({
    width: dimensions.width,
    height: dimensions.height,
  });

  // 监听窗口尺寸变化,同步更新SharedValue
  useEffect(() => {
    screenDimensions.value = {
      width: dimensions.width,
      height: dimensions.height,
    };
  }, [dimensions]);

  // ...
};

2. 修改frameProcessor,用runOnUI调度SharedValue更新

将修改pose.value的代码包裹在runOnUI中,调度到UI线程执行,同时从SharedValue中读取屏幕尺寸:

const frameProcessor = useFrameProcessor((frame) => {
  'worklet';
  const poseObject = objectDetect(frame);

  // 从SharedValue安全获取屏幕尺寸
  const { width: screenWidth, height: screenHeight } = screenDimensions.value;
  const xFactor = screenWidth / frame.width;
  const yFactor = screenHeight / frame.height;

  const poseCopy = { ...defaultPose };
  Object.keys(poseObject).forEach((v) => {
    poseCopy[v] = {
      x: poseObject[v].x * xFactor,
      y: poseObject[v].y * yFactor,
    };
  });

  // 调度到UI线程修改SharedValue
  runOnUI(() => {
    pose.value = poseCopy;
  })();
}, [screenDimensions]);

3. 优化usePosition hook的SharedValue访问

确保在useAnimatedProps的worklet中正确读取SharedValue的当前值:

const usePosition = (pose, valueName1, valueName2) => {
  return useAnimatedProps(
    () => {
      const currentPose = pose.value;
      return {
        x1: currentPose[valueName1].x,
        y1: currentPose[valueName1].y,
        x2: currentPose[valueName2].x,
        y2: currentPose[valueName2].y,
      };
    },
    [pose],
  );
};

修改后效果

应用将正常启动相机,姿态检测结果会通过SharedValue安全同步到UI线程,动画线条会正确跟随检测到的人体关节位置绘制。

内容的提问来源于stack exchange,提问作者SetchFrank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:03:09