(Dioxus) Android Dev Setup for Arch Linux

Tags:

android

Info - TL;DR

Dioxus docs are a bit short for the android specific dev setup, so this is 50% ranting about androids dev setup and 50% documenting said setup with a nix flake automating it at the end.

I moved to Bilbao and I am missing some features from the local public transport applications. So, I thought: an Android app, its gonna be easy, right? Java sucks, Google stinks, but how hard can it be?

First I decided to investigate react native: Just to be quickly disgruntled by the 15 configuration files and the .claude and AGENTS.md file generated upon bun create expo --template default@sdk-571, and finding out a native module2 needs to go through typescript->kotlin|java->rust or one uses jsi-rs. The latter seems to at least partially abstract over the former.

I decided to check out dioxus next, I heard good things and their examples and documentation looked fairly comprehensive and clean, on the first dx serve --android, I got a nice panic Result::unwrap() on an Err value in BuildRequest::start_android_sim somehow the emulator doesnt exist but the dioxus check for it misses that and the panic after checking if the android tools exist is therefore able to happen. I also had some issues with dioxus not expanding tileds to $HOME and thus not being able to find llvm.

If youre asking yourself or me why i have not used the AUR packages Arch Wiki>Android>App dev recommends? The short answer is always permission issues, the long answer is the packages reside in /opt/android-{sdk,ndk} and the sdk wants to edit itself, which it cant due to perms being 0755.

Below is the setup that fixed all my issues and got Dioxus targeting Android working on Arch Linux (good luck to you that it also fixes your issues :#):

Installing Dependencies

Install android studio first:

Android studio

In the Android Studio SDK Manager, install:

  • Android SDK
  • Android SDK Command-line Tools
  • NDK (Side by side)
  • cmake

See Dioxus Mobile App>Android and Android Studio

Rust targets

Then add rust targets:

SHELL
1rustup target add \
2    aarch64-linux-android \
3    armv7-linux-androideabi \
4    i686-linux-android x86_64-linux-android

Configuring shell and path

Then define (path ofc changing depending on install path):

SHELL
1export ANDROID_HOME=/home/teo/Android/Sdk
2export ANDROID_SDK_ROOT=/home/teo/Android/Sdk
3export ANDROID_NDK_HOME=/home/teo/Android/Sdk/ndk/30.0.16138531

Also add the platform tools and the emulator to your path:

SHELL
1export PATH="$PATH:$ANDROID_HOME/emulator"
2export PATH="$PATH:$ANDROID_HOME/platform-tools"
3export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin"

Configuring the Android emulator

By default there are no sdk packages installed required to “create” an emulator, so we need to first install the SDK. I went with 37.0 here, which is Android 17, because its latest and my android device runs it:

SHELL
1android sdk install \
2    platform-tools \
3    emulator \
4    platforms/android-37.0 \
5    system-images/android-37.0/google_apis/x86_64

Then we create an emulator (technically an android virtual device [AVD]):

SHELL
1# omitting --profile results in it being named medium_phone
2android emulator create

Starting the Android emulator

And then we can finally use it to actually start it:

SHELL
1android emulator start medium_phone

And thats just to make sure it works, now the official dioxus docs pick back up and we can run:

SHELL
1dx serve --android

And see the emulator start up and our app boot

Alternatively: A Nix flake

Putting it together into a nix flake:

NIX
 1{
 2  description = "Dioxus Android development environment";
 3
 4  inputs = {
 5    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
 6    rust-overlay.url = "github:oxalica/rust-overlay";
 7  };
 8
 9  outputs = { self, nixpkgs, rust-overlay }:
10    let
11      system = "x86_64-linux";
12
13      pkgs = import nixpkgs {
14        inherit system;
15        overlays = [ rust-overlay.overlays.default ];
16      };
17
18      rust = pkgs.rust-bin.stable.latest.default.override {
19        targets = [
20          "aarch64-linux-android"
21          "armv7-linux-androideabi"
22          "i686-linux-android"
23          "x86_64-linux-android"
24        ];
25      };
26    in
27    {
28      devShells.${system}.default = pkgs.mkShell {
29        packages = with pkgs; [
30          rust
31          android-tools
32        ];
33
34        shellHook = ''
35          export ANDROID_HOME="$HOME/Android/Sdk"
36          export ANDROID_SDK_ROOT="$ANDROID_HOME"
37          export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/30.0.16138531"
38          export PATH="$PATH:$ANDROID_HOME/emulator"
39          export PATH="$PATH:$ANDROID_HOME/platform-tools"
40          export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin"
41        '';
42      };
43    };
44}

The issue being: android studio isnt (AFAIK) fully managed by the nix store; meaning, things like creating android virtual devices are made outside of the nix context and thus I decided to not make android studio subject to the nix flake. Also please make sure to change the ndk path, since I have installed version 30.0.16138531 and you maybe have not :)


  1. expo even added a --no-agents-md, but of course by default you get the clanker integrations ↩︎

  2. I intent to write the logic for routing, data [de]serialisation and the general navigation core in Rust ↩︎