ndk icon indicating copy to clipboard operation
ndk copied to clipboard

Any recommended way of integrating with Java/Kotlin code in an .aar library

Open rib opened this issue 3 years ago • 3 comments

Hi, I'm trying to determine if it makes sense to try and use cargo-apk vs rolling something more hacky/specific while I'm not currently sure how to be able to integrate with Java code that's packaged as an .aar library.

In my case I'd like to be able to package, deploy and test code that will eventually be deployed as part of a Unity 3D application where I have a rust plugin and I'd like to use JNI to access bluetooth apis on Android.

Notably the Unity build system can conveniently let me drop in an .aar library with my compiled/packaged Java code so ideally I'd like to be able to build + deploy my own rust-based test harness in a similar way with the Java code provided as an aar library. (The turn around when building directly with Unity is terrible so I'm looking for a way to more rapidly build and test things in development)

If cargo-apk could perhaps also drive building the aar library, or something similar via gradlew that could also be convenient. I imagine it would be asking too much for cargo-apk to be handling the actual compilation of java code and way out of scope to handle pulling in java dependencies.

Are there perhaps some example projects that aren't purely native that give some ideas for how to best manage pulling together more complex packages that are a mixture of both native and non-native code?

Is there perhaps some way that I can tell cargo-apk to please include a given .aar library?

rib avatar May 14 '21 16:05 rib

I think cargo-apk works great if you only rely on the NativeActivity and want to do your rendering in gl/vulkan. However if you want to integrate with custom java libraries or need to do things not supported with the NativeActivity, like services for example, I think cargo-mobile might be more appropriate. I think it allows you to build your rust code as a dynamic library and integrate it with the gradle/xcode build systems. (I haven't actually used cargo-mobile myself, so I might be mistaken)

NOTE: I'm also not particularly familiar with java so maybe it wouldn't be that hard to support

dvc94ch avatar May 14 '21 16:05 dvc94ch

Okey, thanks for the pointer I should take a look.

I'm not really experienced with java dev either but just thinking about supporting Java compilation I do recall using Meson a few years ago with an Android project which did try and handle compiling java for us too. I think the issue there isn't really with how difficult it is to compile the java code itself (relatively simple) - the bigger problem is that you quickly realise that you need to interact with Maven repos and such to download various dependencies for anything beyond a Hello World test and then things quickly get out of hand and so in practice I think you kinda end up forced to use something like Gradle to deal with the non-native side of things without really trying to boil the ocean - which is a shame since Gradle is a monster :/

My current thinking is that I guess I'll use Gradle to at least build the non-native side of things into an .aar library and then I'm hoping I can find a neat way of building/packaging/deploying a simple test harness for my plugin.

Maybe cargo-mobile is more along the lines of what I need I'll check it out, thanks again.

rib avatar May 14 '21 17:05 rib

We recently did this in our project, so it's definitely possible! Initially we used cargo apk to build our shared objects from a gradle task, and then copy them into libs/ prior to task that creates the AAR. We switched to using Mozilla's rust-android-gradle which does pretty much the same thing as shelling out to cargo apk did (and we still use ndk_glue; it doesn't care which build tool is used).

We're also using Java code with Rust, and we achieve that by using the JNI crate to register native functions (implemented in Rust) and to call Java code from Rust. So nothing in these crates (ndk, ndk-glue, etc) prevents nice interop with Java, and you can certainly use Java to provide an Android-ish API for your Rust code. You can also distribute your AAR containing Rust binaries via Maven so downstream projects from you can incorporate your library via gradle, too.

iamralpht avatar Jul 29 '21 04:07 iamralpht

@iamralpht have you got any example of the shift? Interested but don't know where to start.

Also, is your app more like kotlin/java based and rust is glued into it?

And, how is rust's main() is called? System.loadLibrary()?

Animeshz avatar Oct 11 '22 11:10 Animeshz