17

I haven't done Android development in a while, so my knowledge of modern Android development is spotty.

I'm trying to learn React Native. I use WSL as my primary development environment. Since it'll probably be a pain to set up the Android emulator in Linux/WSL, I want to run the emulator directly on Windows. However, I'd prefer to be able to run react-native run-android in WSL.

How would I set up React Native to be able to run react-native run-android in WSL and run the app in an Android emulator on Windows?

My ANDROID_HOME variable should be set up correctly, but I don't know enough about Android to know if this is doing anything:

export ANDROID_HOME=/mnt/c/Users/Leo/AppData/Local/Android/sdk
export PATH=${PATH}:${ANDROID_HOME}/tools
export PATH=${PATH}:${ANDROID_HOME}/platform-tools
Leo Jiang
  • 24,497
  • 49
  • 154
  • 284
  • Here is a working solution https://stackoverflow.com/questions/67912223/running-wsl2-and-android-studio-at-the-same-time-with-a-ryzen-processor – otocon Jul 13 '21 at 21:29

5 Answers5

24

It is possible to set it up so that the emulator runs in Windows while running react-native run-android in WSL. The benefits of doing it this way over @pscl's way is that this way supports autolinking. Here is what you need to do to get it working.

Windows

The only thing required on the Windows side is to install Android Studio and setup the emulator / virtual device. This is pretty straightforward so I'm not gonna walk you through that.

Windows Subsystem for Linux

There's a bit more to setting up this side of things, so bear with me. (My WSL is Ubuntu 18.04, this is untested on other flavors.)

  1. Download and unzip the Android command line tools. (Currently found on the Android Studio download page, scroll down to "Command line tools only" and select the Linux download option.)
  2. Look inside the unzipped folder and move the directory named tools to ~/Android/Sdk/tools. (Create the ~/Android/Sdk directories if they don't exist.)
  3. Download and unzip JDK 8. (I recommend downloading from AdoptOpenJDK. Also, make sure to install OpenJDK 8 otherwise sdkmanager won't work, which we use later.)
  4. Move the unzipped folder to /opt/jdk8u222-b10. (You can actually put this wherever you want, just make sure the JAVA_HOME environment variable points to this unzipped folder.)
  5. Set the following environment variables in your ~/.bashrc file. (The paths could be different for you!)
export ANDROID_HOME=/home/your-name/Android/Sdk
export JAVA_HOME=/opt/jdk8u222-b10
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
  1. Restart your bash terminal and execute the command sdkmanager "platform-tools" to download the latest platform tools. (The adb tool comes from here.)

React Native

Now that everything is setup, it's time to play!

  1. Start the emulator in Windows.
  2. Open your project directory in WSL and run react-native start. (Keep this terminal open).
  3. Open your project directory in another WSL terminal and run react-native run-android. (The first time you run this, React Native will download a few other SDKs based on your virtual device. You can see all installed SDKs by running sdkmanager --list. See the docs for sdkmanager for more info.)

Running on Device

This is a quick note on making it so you can install your app to a physical device. The trick here is making sure both of your adb executables are on the same version. (They should be since we installed it through sdkmanager.)

C:\Users\your-name\AppData\Local\Android\Sdk\platform-tools\adb.exe version
/home/your-name/Android/Sdk/platform-tools/adb version

Once you've confirmed that they are on the same version, make sure you start the adb server from the windows executable (Run adb.exe kill-server && adb.exe start-server). Then you can test if it works by running adb devices in WSL and you should see your device that is plugged in.

kipper_t
  • 387
  • 3
  • 12
Aust
  • 11,552
  • 13
  • 44
  • 74
  • 2
    I installed JDK with "sudo apt install openjdk-8-jdk". So I skipped steps 3 and 4, also skipped exporting $JAVA_HOME, and worked great. – Wolfdog Dec 14 '19 at 16:16
  • @Wolfdog Oh cool I didn't know openjdk was available via apt, good catch. – Aust Dec 16 '19 at 16:30
  • 1
    Thank you! A couple of notes. First, make sure for step one you download the Linux version. For step 3 I used `sudo apt install openjdk-8-jdk` but it did not set up `JAVA_HOME`. I probably broke it. I had to set it like this site explains. https://vitux.com/how-to-setup-java_home-path-in-ubuntu/. ```bash export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 ``` – bcbrian Dec 24 '19 at 20:37
  • Wonderful answer. This allows me to dev the way I expect to dev without needing to break out the tooling more than required. This should be the accepted answer now. The only bit I have not tested is the physical device part. – kipper_t Jan 20 '20 at 20:28
  • I've followed this guide, but I can't run my app in emulator. Currently, `adb devices` in wsl shows nothing, after I start to run emulator in Windows. but `adb.exe devices` in CMD shows an emulator. How can I run my app in emulator? – mununki Jan 28 '20 at 18:04
  • I'm having the same problem as @moondaddi. It looks like the issue is that my WSL environment is looking at /home/name/Android/sdk/platform-tools/adb while my Windows environment is looking at C:\Users\name\Loca\Android\Sdk\platform-tools\adb.exe. This is causing errors when starting react-native since it's unable to find any connected devices. – Kaidao Jan 30 '20 at 05:42
  • @Kaidao and moondaddi, Have you made sure to follow the section *Running on Device*? – Aust Jan 30 '20 at 17:31
  • @Aust - Yeah, my adb versions are both the same (1.0.41, though pointing at different locations), and I've tried to run `adb.exe start-server` from PowerShell, then trying `adb devices` from WSL, but no devices show up. Also, just a note - but when I run `start-server` from PowerShell, it starts up a server on a port, then when I run `adb devices` from WSL, it also starts up a port (same port number as PowerShell). – Kaidao Jan 30 '20 at 17:52
  • @Aust Sure, I've tried `Running on Device` part. But I have an exactly same issue as @Kaidao has. – mununki Jan 31 '20 at 00:06
  • I've got everything setup like this (had a little issue with ADB versions mismatching which I've resolved). My list of devices in WSL2 however is always empty - do you know why this might be? – Ian Feb 11 '20 at 10:03
  • How to setup `adb` and `java` in WSL for Android Studio in Windows. I tried so many times and failed.. – Ramesh-X Jun 18 '20 at 02:11
  • 2
    I've followed this guide and it works as expected: https://gist.github.com/bergmannjg/461958db03c6ae41a66d264ae6504ade#enable-access-to-adb-server-from-wsl2. The step that's missing here is how you make the adb client in WSL connect to the adb server running in Windows. – bogdanciobanu Jul 06 '20 at 07:08
  • Make sure your windows firewall is set up correctly. You will need to check both "private" and "public" networks for adb.exe or add a custom rule for your WSL2 subnet. – Farcaller Apr 29 '21 at 20:41
17

AFAIK it is not possible to use react-native in WSL due to a number of issues.

e.g. https://github.com/Microsoft/BashOnWindows/issues/1523

However, I've found a workaround that combines a native windows android build with a npm stack in WSL. Realistically, you'll want to install the native Windows Android Studio/SDK to use the Intellij IDE and the emulator anyway. The trick is to separate out the Gradle based Android compile.

Workflow

All project setup and package management performed in WSL with npm/yarn. react-native-cli installed globally in WSL. No need for a duplicate windows binary node/npm stack.

Don't use react-native run-android, instead compile and deploy from cmd. From the /android directory inside your project, execute the gradle wrapper gradlew.bat installDebug, or with the Creator's Update, you can do this from inside the WSL bash shell /mnt/c/Windows/System32/cmd.exe /C gradlew.bat installDebug. Don't use the unix gradlew script.

Once the APK has been assembled and uploaded to your device or emulator, run the debug server from within WSL using the command react-native start.

I've tested this out with some fairly complex projects using multiple native Android components. Hope this helps.

  • Note: For this to work your project needs to be located in the native Windows file system i.e. /mnt/c.
pscl
  • 3,322
  • 25
  • 29
3

For those who struggle to make Windows 10 Android Studio work with WSL2 located react-native project.

Inital setup

You need to install on your Windows 10 Android Studio.

Set user variable: ANDROID_HOME=C:\Users\<YOUR_USER>\AppData\Local\Android\Sdk

Add to system variable PATH: %ANDROID_HOME%\emulator %ANDROID_HOME%\platform-tools %ANDROID_HOME%\tools %ANDROID_HOME%\cmdline-tools\latest (I'm not sure if this one is necessary)

Then go to your WSL2 and install:

  1. sudo apt-get install unzip
  2. get android studio Command Line Tools Only and unzip it into /home//Android
  3. install jdk 8 with sudo apt-get install openjdk-8-jdk
  4. add this to your .bashrc:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export JRE_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre
export PATH=$PATH:$JAVA_HOME/bin

export ADB_SERVER_SOCKET=tcp:<YOUR_WSL_IP_ADDRESS_FROM_POWERSHELL>:5037 (check your WSL adapter IP by running `ipconfig` in powershell.)

export ANDROID_HOME=$HOME/Android
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
  1. restart bash and run sdkmanager --sdk_root=${ANDROID_HOME} "platform-tools"
  2. run adb version && adb.exe version check if versions match

Running on emulator

  1. run adb kill-server (ps) / adb.exe kill-server (wsl2 bash)
  2. run adb -a -P 5037 nodaemon server (ps) / adb.exe -a -P 5037 nodeamon server (wsl2 bash) - don't close terminal window!
  3. run emulator -avd <YOUR_AVD_NAME> (ps) / emulator.exe -avd <YOUR_AVD_NAME> - don't close terminal window!
  4. run adb kill-server (WSL2 bash)
  5. run adb devices (WSL2 bash) - you should now see your emulated device pick up it's id
  6. go to your react-native project directory in WSL2 and run react-native run-android --deviceId=<YOUR_DEVICE_ID>
  7. you should be all set up now.

Same flow stays for USB connected devices. The only thing that is changing is that instead of step 4 you connect your developer enabled phone to PC and you should get in a terminal window with running adb server log that new device is connected.

NOTE: You can run all commands in PowerShell by aliases without .exe and path only if you have defined environmental variables on windows 10 and extended PATH system variable. If you want to use all commands from WSL2 bash you always need to add .exe when you want to execute something on windows side so WSL2 knows that it needs to reach to windows executables.

LukaszKuciel
  • 31
  • 1
  • 2
  • As noted here https://dev.to/mikolaj6r/web-react-native-development-in-wsl-59eh you can use `export WSL_HOST=$(tail -1 /etc/resolv.conf | cut -d' ' -f2)` and then `export ADB_SERVER_SOCKET=tcp:$WSL_HOST:5037` to avoid manually searching/modifying WSL host IP address – TBG Oct 09 '20 at 15:16
  • when I run `adb -a -P 5037 nodaemon server` it always freeze after `adb.exe I 05-13 17:07:18 7556 14388 adb.cpp:175] c3914f31: offline` – Menna Magdy May 13 '22 at 15:12
  • on jdk11 it throws `java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema` – Emaborsa Jan 19 '23 at 13:21
2

This answer by steelbrain from here worked for me:

Add the following to your WSL bashrc or zshrc:

export WSL_HOST_IP="$(tail -1 /etc/resolv.conf | cut -d' ' -f2)"
export ADB_SERVER_SOCKET=tcp:$WSL_HOST_IP:5037

Then create a firewall entry, create a new "Inbound" Rule. Select "Port" then Specific TCP port "5037" then "Allow the connection" then check all of Domain, Private and Public and add a name. After the firewall entry is added, open up its properties, go to Scope -> Remote IP Addresses -> Add "172.16.0.0/12".

Now that we're covered in the WSL2 VM and through the Firewall, you have to start the adb server with specific arguments to make it listen on all addresses (don't worry we've only whitelisted our WSL2 VM IP range so no security issues).

Create a vbs script, call it whatever and put this in it

CreateObject("WScript.Shell").Run "%USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe kill-server", 0, True
CreateObject("WScript.Shell").Run "%USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe -a -P 5037 nodaemon server", 0, True

Now all you have to do is invoke the vbs script once per reboot and your WSL VM will connect to your host ADB instance

(I just invoked those two commands in a regular CMD.exe shell:

%USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe kill-server
%USERPROFILE%\AppData\Local\Android\Sdk\platform-tools\adb.exe -a -P 5037 nodaemon server

I guess he proposed vbs so it remains running, because if I were to put it in a .bat file the server would presumably die with the bat file, haven't tried)

Aur Saraf
  • 3,214
  • 1
  • 26
  • 15
0
ANDROID_HOME=/mnt/c/Users/<YOUR_USER>/AppData/Local/Android/Sdk
alias adb=$ANDROID_HOME"/platform-tools/adb.exe"