Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading custom Java classes #82

Open
DataTriny opened this issue May 5, 2023 · 2 comments
Open

Loading custom Java classes #82

DataTriny opened this issue May 5, 2023 · 2 comments

Comments

@DataTriny
Copy link

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!

@rib
Copy link
Collaborator

rib commented 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 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.

@DataTriny
Copy link
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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants