Reputation: 1569
Currently libraries(.so) are built using visual studio and placed on to jniLibs directory. As shown below,
Getting below exception while finding the class in JNI call (here it is TWMainActivity but true with any other class),
2021-07-23 08:10:43.992 13617-1658/com.tally.twandroidconsolesimulator A/onsolesimulato: java_vm_ext.cc:578] JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.tally.twandroidconsolesimulator.TWMainActivity" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/lib64]]
java_vm_ext.cc:578] at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:207)
java_vm_ext.cc:578] at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
java_vm_ext.cc:578] at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
java_vm_ext.cc:578]
java_vm_ext.cc:578] in call to GetMethodID
While via global reference to the object passed via JNI call (java to C++) able to get the jclass
.
//this is working
jclass cls = env->GetObjectClass (sMainActivityGlobalRef);
//this is not working throwing mentioned exceptions
// jclass cls = env->FindClass ("com/tally/twandroidconsolesimulator/TWMainActivity");
Note: the same code is working with Andrdoid Studio Native project without having jniLibs
Basic code flow as follows,
public class TWMainActivity extends AppCompatActivity {
static {
System.loadLibrary("TWXPControlsGalleryApp_arm64-v8a");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InitializeMain();
}
public native void InitializeMain();
}
//Native code
static void
NativeThread(JavaVM * pJavaVm, jint pJVersion, jobject pObjGblRfrnc){
JNIEnv * env;
auto get_env_result = vm->GetEnv ((void **) &env, pJVersion);
if (get_env_result == JNI_EDETACHED) {
if (vm->AttachCurrentThread (env, nullptr) != JNI_OK) {
return;
}
}
jclass cls = env->FindClass ("com/tally/twandroidconsolesimulator/TWMainActivity");
//... rest of the code follows here
}
extern "C" JNIEXPORT void JNICALL
Java_com_tally_twandroidconsolesimulator_TWMainActivity_InitializeMain (JNIEnv * pEnv, jobject pObj)
{
JavaVM * sJavaVm;
jint jv_version = pEnv->GetVersion ();
pEnv->GetJavaVM (&sJavaVm);
jobject ref = pEnv->NewGlobalRef (pObj);
std::thread thread1 (NativeThread, sJavaVm, jv_version, ref );
thread1.detach ();
}
have referred this, this, this,this but didn't help to rectify the problem.
Environment:
classpath "com.android.tools.build:gradle:4.2.1"
I appreciate any hint.
Upvotes: 1
Views: 410
Reputation: 58427
FindClass
will not be able to find any of your app-specific classes if invoked on a purely native thread, due to the wrong classloader being used. See this section in the Android developer documentation for more information.
There are various ways in which you could solve this, but the easiest is probably to resolve all classes in JNI_OnLoad
, create global references to them, and save those global references somewhere where the rest of your code can access them.
Upvotes: 1