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 d
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.
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.
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.
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.)
tools
to ~/Android/Sdk/tools
. (Create the ~/Android/Sdk
directories if they don't exist.)sdkmanager
won't work, which we use later.)/opt/jdk8u222-b10
. (You can actually put this wherever you want, just make sure the JAVA_HOME
environment variable points to this unzipped folder.)~/.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
sdkmanager "platform-tools"
to download the latest platform tools. (The adb
tool comes from here.)Now that everything is setup, it's time to play!
react-native start
. (Keep this terminal open).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.
For those who struggle to make Windows 10 Android Studio work with WSL2 located react-native project.
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:
sudo apt-get install unzip
sudo apt-get install openjdk-8-jdk
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
sdkmanager --sdk_root=${ANDROID_HOME} "platform-tools"
adb version && adb.exe version
check if versions matchadb kill-server
(ps) / adb.exe kill-server
(wsl2 bash)adb -a -P 5037 nodaemon server
(ps) / adb.exe -a -P 5037 nodeamon server
(wsl2 bash) - don't close terminal window!emulator -avd <YOUR_AVD_NAME>
(ps) / emulator.exe -avd <YOUR_AVD_NAME>
- don't close terminal window!adb kill-server
(WSL2 bash)adb devices
(WSL2 bash) - you should now see your emulated device pick up it's id react-native run-android --deviceId=<YOUR_DEVICE_ID>
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.
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)