9 months ago
- Android presents unique challenges for Rust developers due to limited access to certain OS functions compared to desktop platforms.
- Advanced phone capabilities, like Bluetooth control, are only accessible via Android's Java SDK, not through native libraries like libc or the NDK.
- JNI (Java Native Interface) allows Rust to interact with Java APIs, enabling the use of Java classes and methods from native code.
- Previously, it was believed that Rust on Android couldn't create new Java classes, only instantiate existing ones, limiting functionality.
- For app developers, adding necessary Java classes isn't an issue, but it's problematic for Rust library developers whose users might not know to include these classes.
- Android's JNI documentation states that `DefineClass` isn't supported, but using `DexClassLoader` allows injecting pre-compiled Java classes at runtime.
- Rust crates can embed and inject Java classes (via `classes.dex`) into the JVM, making the process seamless for users.
- The process involves compiling `.java` files into `.class` files, converting them to `classes.dex`, embedding them in the Rust library, and loading them at runtime.
- This technique, though not widely known, enables modular Rust libraries on Android, similar to the ease of iOS development with C or ObjC interfaces.
- Examples include the `slint` and `netwatcher` crates, which use this approach to provide Java helpers without user intervention.