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
相关产品推荐
相关产品推荐

