From 997642d93acaddb6626a0984932f6af6b293934f Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Sat, 20 May 2023 19:23:40 +0200 Subject: [PATCH] auto find main activity using AndroidManifest.xml --- src/api-impl-jni/util.c | 5 +++-- src/api-impl/android/app/Activity.java | 28 ++++++++++++++++++++++++++ src/main-executable/main.c | 5 ----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/api-impl-jni/util.c b/src/api-impl-jni/util.c index f241312f..55c50a2d 100644 --- a/src/api-impl-jni/util.c +++ b/src/api-impl-jni/util.c @@ -43,10 +43,11 @@ void set_up_handle_cache(JNIEnv *env, char *apk_main_activity_class) { (*env)->GetJavaVM(env, &jvm); - handle_cache.apk_main_activity.class = _REF((*env)->FindClass(env, apk_main_activity_class)); + handle_cache.apk_main_activity.class = _REF((*env)->FindClass(env, "android/app/Activity")); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); - handle_cache.apk_main_activity.object = _REF((*env)->NewObject(env, handle_cache.apk_main_activity.class, _METHOD(handle_cache.apk_main_activity.class, "", "()V"))); + jmethodID createMainActivity = _STATIC_METHOD(handle_cache.apk_main_activity.class, "createMainActivity", "(Ljava/lang/String;)Landroid/app/Activity;"); + handle_cache.apk_main_activity.object = _REF((*env)->CallStaticObjectMethod(env, handle_cache.apk_main_activity.class, createMainActivity, _JSTRING(apk_main_activity_class))); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); handle_cache.apk_main_activity.onCreate = _METHOD(handle_cache.apk_main_activity.class, "onCreate", "(Landroid/os/Bundle;)V"); diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index 3b583c98..ae39c506 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -18,14 +18,42 @@ import android.view.WindowManagerImpl; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; +import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; + import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; import java.io.StringReader; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; public class Activity extends Context { LayoutInflater layout_inflater; Window window = new Window(); int requested_orientation = -1 /*ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED*/; // dummy + /** + * Helper function to be called from native code to construct main activity + * + * @param className class name of activity or null + * @return instance of main activity class + */ + private static Activity createMainActivity(String className) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { + if (className == null) { + InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); + AndroidManifestBlock block = AndroidManifestBlock.load(inStream); + className = block.getMainActivity().searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); + if (className.startsWith(".")) { + className = block.getPackageName() + className; + } + } else { + className = className.replace('/', '.'); + } + Class cls = Class.forName(className).asSubclass(Activity.class); + Constructor constructor = cls.getConstructor(); + return constructor.newInstance(); + } + protected void set_window(long native_window) { window.native_window = native_window; } diff --git a/src/main-executable/main.c b/src/main-executable/main.c index 32c6719f..4db7e566 100644 --- a/src/main-executable/main.c +++ b/src/main-executable/main.c @@ -280,11 +280,6 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h free(app_lib_dir); - if(!d->apk_main_activity_class) { - printf("error: missing required option --launch-activity .\nyou can specify --help to see the list of options\n"); - exit(1); - } - set_up_handle_cache(env, d->apk_main_activity_class); jclass display_class = (*env)->FindClass(env, "android/view/Display");