java.lang.ClassNotFoundException: 在路径上:DexPathList[[目录“.”],nativeLibraryDirectories=[/system/lib64, /system/lib64]]

java.lang.ClassNotFoundException: on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system/lib64]]

目前,库 (.so) 是使用 visual studio 构建的,并放置在 jniLibs 目录中。 如下图,

在 JNI 调用中找到 class 时出现以下异常(这里是 TWMainActivity 但对于任何其他 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

虽然通过对通过 JNI 调用(java 到 C++)传递的对象的全局引用能够获得 jclass.

   //this is working
    jclass      cls = env->GetObjectClass (sMainActivityGlobalRef);

   //this is not working throwing mentioned exceptions
  //  jclass       cls = env->FindClass ("com/tally/twandroidconsolesimulator/TWMainActivity");

注意:相同的代码在没有 jniLibs 的情况下适用于 Andrdoid Studio Native 项目

基本代码流程如下,

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();
 }

//原生代码

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 ();
}

已提及 this, , this,this 但没有帮助解决问题。

环境:

    classpath "com.android.tools.build:gradle:4.2.1"

感谢任何提示。

由于使用了错误的类加载器,

FindClass 如果在纯本机线程上调用,类 将无法找到您的应用程序特定的任何内容。有关详细信息,请参阅 Android 开发人员文档中的 this section

有多种方法可以解决这个问题,但最简单的方法可能是解决 JNI_OnLoad 中的所有 类,创建对它们的全局引用,并将这些全局引用保存在您的其余代码可以访问它们。