You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成Google Cardboard SDK时出现BaseDexClassLoader类找不到异常

问题分析

运行Cardboard_initializeAndroid时触发ClassNotFoundException,找不到CardboardParamsUtils和QrCodeCaptureActivity,但APK中存在对应smali文件;minSdkVersion=26默认开启Multidex,原生代码编译正常,异常来自qr_code.cc的LoadJNIResources函数。

解决方案

1. 修正JNI类加载逻辑

原生代码加载Java类时可能使用了系统类加载器,导致找不到应用内的类。修改qr_code.cc的LoadJNIResources函数,改用应用上下文的类加载器查找类:

// 获取应用上下文的类加载器
jclass context_cls = env->FindClass("android/content/Context");
jmethodID get_class_loader = env->GetMethodID(context_cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject class_loader = env->CallObjectMethod(android_context, get_class_loader);
env->DeleteLocalRef(context_cls);

// 通过类加载器加载目标类
jclass loader_cls = env->FindClass("java/lang/ClassLoader");
jmethodID load_class = env->GetMethodID(loader_cls, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");

// 加载CardboardParamsUtils
jstring params_utils_name = env->NewStringUTF("com.google.cardboard.sdk.qrcode.CardboardParamsUtils");
jclass params_utils_cls = (jclass)env->CallObjectMethod(class_loader, load_class, params_utils_name);
env->DeleteLocalRef(params_utils_name);

// 加载QrCodeCaptureActivity
jstring capture_activity_name = env->NewStringUTF("com.google.cardboard.sdk.QrCodeCaptureActivity");
jclass capture_activity_cls = (jclass)env->CallObjectMethod(class_loader, load_class, capture_activity_name);
env->DeleteLocalRef(capture_activity_name);
env->DeleteLocalRef(loader_cls);

2. 补充ProGuard混淆规则

release构建开启了代码混淆,即使smali存在,也可能因类名被修改导致加载失败。在模块的proguard-rules.pro中添加保留规则:

# 保留Cardboard SDK所有类及方法
-keep class com.google.cardboard.sdk.** { *; }
-keep class com.google.cardboard.proto.** { *; }
# 保留JNI关联方法
-keepclasseswithmembernames class * {
    native <methods>;
}

3. 修复library模块Build配置

你的build.gradle存在重复的defaultConfig块,可能导致配置异常,移除嵌套块:

defaultConfig {
    minSdkVersion 26
    targetSdkVersion 31
    testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
    consumerProguardFiles 'proguard-rules.pro' // 移至外层defaultConfig
}

执行./gradlew clean build清理缓存后重新构建模块,确保sourceSets配置的Java目录和protobuf生成路径无冲突。

4. 验证依赖与打包完整性

  • 确认主项目通过implementation project(...)正确引入Cardboard模块
  • 使用Android Studio的Build > Analyze APK功能,检查APK的classes.dex中是否存在完整的com.google.cardboard.sdk包结构(仅smali存在不代表dex类可正常加载)

5. 调整JNI初始化时机

确保Cardboard_initializeAndroid在Activity创建完成后调用,避免在Application的onCreate早期或未初始化Android上下文时执行,此时类加载器可能未准备就绪。

内容的提问来源于stack exchange,提问作者Stégosaure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:15:03