React Native中Reanimated报错“Reading from _value directly...”解决咨询
解决方案:"Reading from _value directly is only possible on the UI runtime" 错误修复
错误核心原因
- SharedValue跨线程操作违规:
frameProcessor是运行在Vision Camera专用帧处理线程的worklet,直接在其中修改SharedValue的.value属性(pose.value = poseCopy)违反了Reanimated规则——SharedValue的读写必须在UI线程执行。 - 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
相关产品推荐
相关产品推荐

