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

Android Manifest中能否声明多个NativeActivity?无需Java代码实现

无需Java代码创建多个NativeActivity的实现方案

Android系统不允许在Manifest中重复声明同一类的Activity,因此直接声明两个android.app.NativeActivity会触发报错。如果不想手动编写空Java子类,可通过以下两种方式实现:

1. Gradle自动生成空Java子类

通过Gradle任务自动生成继承NativeActivity的空类,无需手动创建Java文件。

Groovy 版本(build.gradle)

task generateSecondNativeActivity {
    def packageDir = file("src/main/java/com/your/actual/package/")
    packageDir.mkdirs()
    def activityFile = new File(packageDir, "SecondNativeActivity.java")
    activityFile.write("""
        package com.your.actual.package;
        import android.app.NativeActivity;
        public class SecondNativeActivity extends NativeActivity {}
    """.trim())
}

preBuild.dependsOn(generateSecondNativeActivity)

Kotlin DSL 版本(build.gradle.kts)

tasks.register("generateSecondNativeActivity") {
    val packageDir = file("src/main/java/com/your/actual/package/")
    packageDir.mkdirs()
    val activityFile = File(packageDir, "SecondNativeActivity.java")
    activityFile.writeText("""
        package com.your.actual.package;
        import android.app.NativeActivity;
        public class SecondNativeActivity extends NativeActivity {}
    """.trimIndent())
}

tasks.preBuild.configure {
    dependsOn("generateSecondNativeActivity")
}

对应Manifest配置

<activity android:name="android.app.NativeActivity">
    <!-- 第一个NativeActivity配置:指定native库、启动逻辑等 -->
    <meta-data
        android:name="android.app.lib_name"
        android:value="first-native-lib" />
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="com.your.actual.package.SecondNativeActivity">
    <!-- 第二个NativeActivity配置:可指定不同的native库或参数 -->
    <meta-data
        android:name="android.app.lib_name"
        android:value="second-native-lib" />
</activity>

2. 复用单个NativeActivity,通过Intent参数区分逻辑

如果不需要两个独立的Activity声明,仅需区分不同的native逻辑入口,可复用单个NativeActivity,通过Intent传递参数切换逻辑。

Manifest配置

<activity android:name="android.app.NativeActivity">
    <meta-data
        android:name="android.app.lib_name"
        android:value="your-native-lib" />
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Native代码中区分逻辑

void android_main(struct android_app* app) {
    // 从Intent获取区分参数
    jclass intentClass = (*app->activity->env)->FindClass(app->activity->env, "android/content/Intent");
    jmethodID getStringExtra = (*app->activity->env)->GetMethodID(app->activity->env, intentClass, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
    jstring typeStr = (*app->activity->env)->CallObjectMethod(app->activity->env, app->activity->intent, getStringExtra, (*app->activity->env)->NewStringUTF(app->activity->env, "activity_type"));
    const char* activityType = (*app->activity->env)->GetStringUTFChars(app->activity->env, typeStr, NULL);

    // 根据参数执行不同逻辑
    if (strcmp(activityType, "second") == 0) {
        run_second_activity_logic(app);
    } else {
        run_first_activity_logic(app);
    }

    // 释放JNI资源
    (*app->activity->env)->ReleaseStringUTFChars(app->activity->env, typeStr, activityType);
    (*app->activity->env)->DeleteLocalRef(app->activity->env, intentClass);
    (*app->activity->env)->DeleteLocalRef(app->activity->env, typeStr);
}

Native代码中启动第二个逻辑实例

void start_second_activity(struct android_app* app) {
    // 创建Intent,指定目标为NativeActivity
    jclass intentClass = (*app->activity->env)->FindClass(app->activity->env, "android/content/Intent");
    jmethodID intentCtor = (*app->activity->env)->GetMethodID(app->activity->env, intentClass, "<init>", "(Landroid/content/Context;Ljava/lang/Class;)V");
    jclass nativeActivityClass = (*app->activity->env)->FindClass(app->activity->env, "android/app/NativeActivity");
    jobject intent = (*app->activity->env)->NewObject(app->activity->env, intentClass, intentCtor, app->activity->clazz, nativeActivityClass);

    // 添加区分参数
    jmethodID putExtra = (*app->activity->env)->GetMethodID(app->activity->env, intentClass, "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;");
    intent = (*app->activity->env)->CallObjectMethod(app->activity->env, intent, putExtra, (*app->activity->env)->NewStringUTF(app->activity->env, "activity_type"), (*app->activity->env)->NewStringUTF(app->activity->env, "second"));

    // 启动Activity
    jclass activityClass = (*app->activity->env)->FindClass(app->activity->env, "android/app/Activity");
    jmethodID startActivity = (*app->activity->env)->GetMethodID(app->activity->env, activityClass, "startActivity", "(Landroid/content/Intent;)V");
    (*app->activity->env)->CallVoidMethod(app->activity->env, app->activity->clazz, startActivity, intent);

    // 释放JNI资源
    (*app->activity->env)->DeleteLocalRef(app->activity->env, intentClass);
    (*app->activity->env)->DeleteLocalRef(app->activity->env, nativeActivityClass);
    (*app->activity->env)->DeleteLocalRef(app->activity->env, intent);
    (*app->activity->env)->DeleteLocalRef(app->activity->env, activityClass);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:25:17