Injecting Java from native libraries on Android
9 months ago
- #JNI
- #Rust
- #Android
- 由于相比桌面平台对某些操作系统功能的访问受限,Android给Rust开发者带来了独特挑战
- 蓝牙控制等高级手机功能只能通过Android的Java SDK访问,无法通过libc或NDK等原生库实现
- JNI(Java本地接口)允许Rust与Java API交互,从而能在原生代码中调用Java类和方法
- 过去普遍认为Android上的Rust无法创建新Java类,只能实例化现有类,这限制了功能实现
- 对应用开发者而言添加必要Java类不是问题,但对Rust库开发者却很棘手——他们的用户可能不知道需要包含这些类
- Android官方JNI文档声称不支持`DefineClass`,但通过`DexClassLoader`可以在运行时注入预编译的Java类
- Rust库可以嵌入并通过`classes.dex`向JVM注入Java类,对用户实现无缝集成
- 该技术流程包括:将.java文件编译为.class文件→转换为classes.dex→嵌入Rust库→运行时加载
- 这种虽不广为人知的技术使Android上的Rust模块化开发成为可能,类似iOS通过C或ObjC接口的便捷开发体验
- 典型案例包括`slint`和`netwatcher`等crate,它们通过此方案自动提供Java辅助类而无需用户额外操作