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

Native Activity中C++调用自定义Java WebView类失败问题排查

解决Native Activity环境下JNI找不到自定义Java类的问题

1. 配置Module级build.gradle

确保Java代码被正确编译打包,同时关联CMake构建流程:

  • 确认sourceSets配置正确识别源码路径,默认src/main/java会被自动扫描,若有自定义路径需明确声明:
android {
    sourceSets {
        main {
            java.srcDirs = ['src/main/java']
            jni.srcDirs = ['src'] // 你的C++代码根目录
        }
    }

    defaultConfig {
        externalNativeBuild {
            cmake {
                path file('CMakeLists.txt') // 指向项目根目录的CMake配置文件
            }
        }
    }

    externalNativeBuild {
        cmake {
            version "3.22.1" // 使用与你的NDK版本适配的CMake版本
        }
    }
}
  • 添加WebView依赖(按需选择对应版本):
dependencies {
    implementation 'androidx.webkit:webkit:1.6.1'
}

2. 修改AndroidManifest.xml

确保Java类可被正确加载,同时配置WebView必需的权限与属性:

<!-- 添加WebView所需权限 -->
<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:hardwareAccelerated="true" <!-- WebView必须开启硬件加速 -->
    android:supportsRtl="true">

    <!-- 声明Native Activity -->
    <activity android:name="android.app.NativeActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data
            android:name="android.app.lib_name"
            android:value="你的Native库名称" /> <!-- 需与CMake配置的库名一致 -->
    </activity>
</application>

3. 修正JNI调用代码

Native Activity的系统类加载器无法识别自定义类,需改用应用类加载器加载:

JNIEnv* env = nullptr;
JavaVM* jvm = gapp->activity->vm;
// 附加当前线程到JVM
int attachResult = jvm->AttachCurrentThread(&env, nullptr);
if (attachResult != JNI_OK) {
    return;
}

// 获取NativeActivity的Java对象
jobject activityObj = gapp->activity->clazz;
// 获取Activity的ClassLoader
jclass activityClass = env->GetObjectClass(activityObj);
jmethodID getClassLoaderMethod = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject classLoaderObj = env->CallObjectMethod(activityObj, getClassLoaderMethod);

// 通过ClassLoader加载自定义类
jclass classLoaderClass = env->FindClass("java/lang/ClassLoader");
jmethodID loadClassMethod = env->GetMethodID(classLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring classNameStr = env->NewStringUTF("com.my.app.CustomWebView"); // 注意用点分隔包名
jclass customWebViewClass = (jclass)env->CallObjectMethod(classLoaderObj, loadClassMethod, classNameStr);

// 释放局部引用
env->DeleteLocalRef(classNameStr);
env->DeleteLocalRef(classLoaderClass);
env->DeleteLocalRef(classLoaderObj);
env->DeleteLocalRef(activityClass);

// 检查加载结果,若失败可打印JNI异常信息
if (customWebViewClass == nullptr) {
    jthrowable exc = env->ExceptionOccurred();
    if (exc) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
}

// 按需分离线程
jvm->DetachCurrentThread();

关键注意点

  • Native Activity默认使用系统类加载器,仅能加载系统类,自定义类必须通过应用级的Activity ClassLoader加载,这是直接调用FindClass失败的核心原因。
  • 确保Java类的包名与文件路径完全对应,src/main/java/com/my/app/CustomWebView.java中必须声明package com.my.app;。
  • CMake配置的Native库名称必须与Manifest中android.app.lib_name的取值一致。

内容的提问来源于stack exchange,提问作者dan123123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:40:33