-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
What's happening?
When the app is in the background (minimized) and the device is turned off, then turned back on, and the app is reopened from the recent apps list, the camera fails to initialize. The camera preview shows no video feed, and the useCameraDevice("back") hook appears to return null or a stale device reference.
Steps to Reproduce
Open the app and navigate to any screen that uses the camera
Minimize the app (send to background)
Turn off the device completely
Turn the device back on
Open the app from the "recent apps" list (not a fresh launch)
Navigate to the camera screen
Actual Behavior
The camera shows a loading state indefinitely ("Cargando cámara...")
After 5 seconds, an alert appears offering to retry
Pressing "Retry" does not fix the issue - the camera still fails to initialize
The only workaround is to completely kill the app (swipe from recents) and launch it fresh
Enviroment:
expo: 53.0.0
react-native-vision-camera": 4.7.3
react-native: 0.79.6
This appears to be related to Android's behavior when terminating a process. When the device shuts down with the app running in the background, Android terminates the app's process. When reopened from recent apps, Android recreates the activity. However, when attempting to use the camera component again, the camera doesn't display an image.
Is there anything in the component's lifecycle that you're not handling well or should take into account?
THANKS!!
Reproduceable Code
React, { useState, useRef, useEffect } from "react";
import {
View,
TouchableOpacity,
Text,
StyleSheet,
Alert,
ActivityIndicator,
AppState,
} from "react-native";
import {
Camera,
useCameraDevice,
useCameraPermission,
} from "react-native-vision-camera";
import { useIsFocused } from "@react-navigation/native";
const CameraScreen = ({ navigation, route }) => {
const { hasPermission } = useCameraPermission();
const device = useCameraDevice("back");
const [previewImage, setPreviewImage] = useState(null);
const [cameraReady, setCameraReady] = useState(false);
const [isCapturing, setIsCapturing] = useState(false);
const cameraRef = useRef(null);
const mountTimeRef = useRef(Date.now());
const hasAttemptedRetry = useRef(false);
const isFocused = useIsFocused();
const [appState, setAppState] = useState(AppState.currentState);
// Handle app state changes
useEffect(() => {
const subscription = AppState.addEventListener("change", (nextAppState) => {
setAppState(nextAppState);
});
return () => subscription.remove();
}, []);
// Camera should be active when focused, app is active, and no preview
const isActive = isFocused && appState === "active" && !previewImage;
// Timeout to detect if camera doesn't initialize (process death scenario)
useEffect(() => {
if (!device) {
const timeout = setTimeout(() => {
if (!device && !hasAttemptedRetry.current) {
hasAttemptedRetry.current = true;
Alert.alert(
"Camera Error",
"Camera could not initialize. Please try again.",
[
{
text: "Retry",
onPress: () => {
navigation.goBack();
setTimeout(() => {
navigation.navigate("Camera", route.params);
}, 100);
},
},
{
text: "Cancel",
onPress: () => navigation.goBack(),
style: "cancel",
},
]
);
}
}, 5000);
return () => clearTimeout(timeout);
} else {
hasAttemptedRetry.current = false;
}
}, [device, navigation, route.params]);
if (device == null) {
return (
<View style={styles.centerContainer}>
<ActivityIndicator size="large" color="#003366" />
<Text>Loading camera...</Text>
</View>
);
}
return (
<View style={StyleSheet.absoluteFill}>
<Camera
ref={cameraRef}
style={StyleSheet.absoluteFill}
device={device}
isActive={isActive}
photo={true}
onError={(error) => console.error("Camera error:", error)}
onInitialized={() => setCameraReady(true)}
onStarted={() => console.log("Camera started streaming")}
onStopped={() => console.log("Camera stopped streaming")}
/>
</View>
);
};Relevant log output
// Timeout triggers after 5 seconds
09:17:59.649 ⚠️ Camera not available after 5019ms - possible process death
// After pressing "Retry" - component remounts but device is STILL null
09:18:03.433 '🔄 CameraScreen mounted - Timestamp:', '2026-01-19T12:18:03.433Z'
09:18:03.433 '📊 Initial state:', { hasPermission: true,
device: 'null',
isFocused: true,
appState: 'active' }
// Timeout triggers again - stuck in infinite loop
09:18:08.450 ⚠️ Camera not available after 5022ms - possible process deathI don't see any VisionCamera logs when this error occurs. Only the console logs of my code.
Camera Device
When I play the problem, device comes out as nullDevice
Samsung Galaxy S25+
VisionCamera Version
4.7.3
Can you reproduce this issue in the VisionCamera Example app?
No, I cannot reproduce the issue in the Example app
Additional information
- I am using Expo
- I have enabled Frame Processors (react-native-worklets-core)
- I have read the Troubleshooting Guide
- I agree to follow this project's Code of Conduct
- I searched for similar issues in this repository and found none.