Hi there!
If you've been working with React Native, you've likely encountered emulator issues. You run the React Native command, but the emulator isn’t detected. Even after setting all the necessary environment variables in your .zshrc, .bash_profile, or similar files, it still doesn’t work.
Here are some common problems and fixes:
Emulator Not Found: This can happen if the Android SDK path isn't correctly set. Double-check that the ANDROID_HOME and PATH environment variables point to the correct directories. You can add these lines to your .zshrc or .bash_profile:
export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-tools
After making these changes, restart your terminal or run source ~/.zshrc (or source ~/.bash_profile).
Watchman Errors: Sometimes, Watchman—Facebook’s file watching service—can cause issues with stale file caches. To fix this, run:
watchman watch-del-all
Then, restart your React Native server.
adb reverse to Connect to localhost: If your app cannot connect to localhost from within the Android emulator, you might need to run:
adb reverse tcp:8081 tcp:8081
This command routes traffic from the emulator to your local machine. Make sure adb is accessible from your terminal.
Clear Cache and Rebuild: If you still face issues, try clearing the cache and rebuilding the project:
npm start -- --reset-cache cd android && ./gradlew clean cd ios && xcodebuild clean
Then run your React Native app again.
Using react-native run-android or run-ios Directly: If the emulator is not starting correctly from your IDE or terminal, try running the app directly with:
npx react-native run-android npx react-native run-ios
Debugging these issues can be frustrating, but these steps have helped me solve many common problems.
I created an easy-to-use script too
const {spawn, exec} = require('child_process'); const path = require('path'); // Define paths const projectPath = path.resolve(); // Define commands const watchDelCommand = `watchman watch-del '${projectPath}'`; const watchProjectCommand = `watchman watch-project '${projectPath}'`; // Function to execute commands const clearWatchman = () => { // Execute watch-del command exec(watchDelCommand, (error, stdout, stderr) => { if (error) { console.error(`Error executing watch-del command: ${error.message}`); return; } if (stderr) { console.error(`stderr: ${stderr}`); return; } console.log(`watch-del command executed successfully: ${stdout}`); // Execute watch-project command exec(watchProjectCommand, (error, stdout, stderr) => { if (error) { console.error( `Error executing watch-project command: ${error.message}`, ); return; } if (stderr) { console.error(`stderr: ${stderr}`); return; } console.log(`watch-project command executed successfully: ${stdout}`); }); }); }; async function reverseAdb() { console.log('Running... adb reverse tcp:8080 tcp:8080'); // After the emulator has started adb reverse tcp:8080 tcp:8080 const adbReverse = spawn('adb', ['reverse', 'tcp:8080', 'tcp:8080']); await new Promise((resolve, reject) => { let output = ''; adbReverse.stdout.on('data', data => { output += data.toString(); }); adbReverse.on('close', () => { resolve(); }); adbReverse.stderr.on('error', reject); }).catch(error => console.error('Error reversing ADB port to 8080:', error)); } async function runEmulator() { try { clearWatchman(); // Check for running emulator const adbDevices = spawn('adb', ['devices']); const devices = await new Promise((resolve, reject) => { let output = ''; adbDevices.stdout.on('data', data => { output += data.toString(); }); adbDevices.on('close', () => { resolve(output.includes('emulator')); }); adbDevices.stderr.on('error', reject); }); if (devices) { console.log('Emulator is already running'); reverseAdb(); return; } // Get list of available emulators const emulatorList = spawn('emulator', ['-list-avds']); const emulatorName = await new Promise((resolve, reject) => { let output = ''; emulatorList.stdout.on('data', data => { output += data.toString(); }); emulatorList.on('close', () => { const lines = output.split('\n').filter(Boolean); // Filter out empty lines if (lines.length === 0) { reject(new Error('No AVDs found')); } else { resolve(lines[lines.length - 1]); // Get the last non-empty line } }); emulatorList.stderr.on('error', reject); }); // Start the emulator in detached mode const emulatorProcess = spawn('emulator', ['-avd', emulatorName], { detached: true, stdio: 'ignore', }); emulatorProcess.unref(); // Allow the parent process to exit independently of the child reverseAdb(); console.log(`Starting emulator: ${emulatorName}`); } catch (error) { console.error('Error running emulator:', error); } } runEmulator(); // package.json "scripts": { ... "dev:android": "yarn android:emulator && npx react-native@latest start", "android:emulator": "node runEmulator.js", ... },
By using the script above, you can run both the emulator and React Native simultaneously.
Thanks for reading!
The above is the detailed content of A Script To Help React Native Developers. For more information, please follow other related articles on the PHP Chinese website!