You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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?
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.
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.
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?
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?
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.
Activity
rib commentedon May 28, 2023
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
jnicrate types in the public API forandroid-activityand then effectively pin downstream crates to the same version of thejnicrate.Hope that helps though.
DataTriny commentedon May 28, 2023
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?
Gibbz commentedon Dec 25, 2024
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?
Support an optional 'android_on_create' entrypoint
Support an optional 'android_on_create' entrypoint
Support an optional 'android_on_create' entrypoint
rib commentedon Mar 19, 2026
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-activitynow callsThead.setContextClassLoaderto associate theandroid_mainthread with a class loader that is able to find Android application classes. If you are then usingjni0.22 in your application then it will automatically check this state if you useenv.load_class().With #236 then we support an optional
android_on_createentrypoint that can serve a similar purpose toJNI_OnLoadin that it lets you run code fromActivity.onCreatewhile the class loader for theActivityis on the stack, and soFindClasswill 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_maintoo but at least for now that's not possible with NativeActivity and GameActivity.