Skip to content

Loading custom Java classes #82

Closed
Closed

Description

@DataTriny

Hi,

I am using the GameActivity and I need to instanciate a Java class that I wrote. This class is not referenced anywhere on the Java side but it is present in the APK. When I call env.find_class inside my android_main function, I get a ClassNotFoundException. I have read that this could happen inside a thread not spawned by the JVM that would use the default ClassLoader. I have also found this comment just before the call to android_main:

// XXX: If we were in control of the Java Activity subclass then
// we could potentially run the android_main function via a Java native method
// springboard (e.g. call an Activity subclass method that calls a jni native
// method that then just calls android_main()) that would make sure there was
// a Java frame at the base of our call stack which would then be recognised
// when calling FindClass to lookup a suitable classLoader, instead of
// defaulting to the system loader. Without this then it's difficult for native
// code to look up non-standard Java classes.

I think this explain my issue. Is there a typical way around this? I've heard about the JNI_OnLoad function, but I'm afraid it would interfear.

How difficult whould it be to lift this limitation, if it is something doable?

Thanks for this amazing crate!

Activity

  1. rib commented on May 28, 2023

    @rib
    Member

    Hi, sorry I missed this question when you asked it.

    Yeah this is an awkward Android + JNI issue for native apps. One option is to look up the class loader for the Activity instance that you have access to and use that instead of find_class.

    E.g. this is what I do in Bluey: https://github.com/rib/bluey/blob/5f351c50e6f396bc4fef9c050599f9668c63b339/bluey/src/android/session.rs#L1017

    Potentially android-activity could provide some kind of utility for this but ideally I don't really want to expose jni crate types in the public API for android-activity and then effectively pin downstream crates to the same version of the jni crate.

    Hope that helps though.

  2. DataTriny commented on May 28, 2023

    @DataTriny
    Author

    Thanks @rib

    For now I ask the user to call a Java method in their GameActivity subclass and I'd like to avoid this if possible. I'll try your approach as it seems to be exactly what I need.
    Maybe this recipe could be added somewhere in the documentation?

  3. Gibbz commented on Dec 25, 2024

    @Gibbz

    a related question. How can i include the aar lib files in my project?
    i currently have them located in proj_root/android/libs/ but theyre not located in the apk file when i build it.
    I figure i need to reference them in a file somewhere so the x build tool knows to add them?

  4. rib commented on Mar 19, 2026

    @rib
    Member

    I think we can hopefully say that this is fixed by the combination of #202 and #239

    With the update to jni 0.22 then android-activity now calls Thead.setContextClassLoader to associate the android_main thread with a class loader that is able to find Android application classes. If you are then using jni 0.22 in your application then it will automatically check this state if you use env.load_class().

    With #236 then we support an optional android_on_create entrypoint that can serve a similar purpose to JNI_OnLoad in that it lets you run code from Activity.onCreate while the class loader for the Activity is on the stack, and so FindClass will automatically be able to find application classes without needing to manually look up the Activity class loader as described in #82 (comment)

    In the future, if we implement a RustActivity maybe we can use a native method springboard for android_main too but at least for now that's not possible with NativeActivity and GameActivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions