Activity: implement Activity.recreate

This commit is contained in:
Mis012
2024-02-19 16:29:09 +01:00
parent 5f3f8a5e6c
commit da0971e88f
3 changed files with 94 additions and 31 deletions

View File

@@ -10,17 +10,48 @@
static GList *activity_backlog = NULL;
static jobject activity_current = NULL;
static jobject activity_toplevel_current = NULL;
static void activity_close(JNIEnv *env, jobject activity)
{
// in case some exception was left unhandled in native code, print it here so we don't confuse it with an exception thrown by onDestroy
if((*env)->ExceptionCheck(env)) {
fprintf(stderr, "app_exit: seems there was a pending exception... :");
fprintf(stderr, "activity.onDestroy: seems there was a pending exception... :");
(*env)->ExceptionDescribe(env);
}
/* -- run the main activity's onDestroy -- */
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onDestroy, NULL);
/* -- run the activity's onDestroy -- */
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onDestroy);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
static void activity_unfocus(JNIEnv *env, jobject activity)
{
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onPause);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onStop);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onWindowFocusChanged, false);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
static void activity_focus(JNIEnv *env, jobject activity)
{
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onStart);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onResume);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity, handle_cache.activity.onWindowFocusChanged, true);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
@@ -28,37 +59,28 @@ static void activity_close(JNIEnv *env, jobject activity)
static void activity_update_current(JNIEnv *env)
{
jobject activity_new = activity_backlog ? g_list_first(activity_backlog)->data : NULL;
jobject activity_toplevel_new = activity_backlog ? g_list_last(activity_backlog)->data : NULL;
if (activity_current != activity_new) {
if (activity_current) {
(*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onPause);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
if (activity_current)
activity_unfocus(env, activity_current);
(*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onStop);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
if (activity_new)
activity_focus(env, activity_new);
(*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onWindowFocusChanged, false);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
if (activity_new) {
(*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onStart);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onResume);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onWindowFocusChanged, true);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
}
activity_current = activity_new;
}
/* for Activity.recreate */
if(activity_toplevel_current != activity_toplevel_new) {
if (activity_toplevel_current)
activity_unfocus(env, activity_toplevel_current);
if (activity_toplevel_new)
activity_focus(env, activity_toplevel_new);
activity_toplevel_current = activity_toplevel_new;
}
}
void activity_window_ready(void)
@@ -89,15 +111,25 @@ void activity_close_all(void)
g_list_free(activities);
}
void activity_start(JNIEnv *env, jobject activity_object)
void _activity_start(JNIEnv *env, jobject activity_object, bool recreate)
{
/* -- run the activity's onCreate -- */
(*env)->CallVoidMethod(env, activity_object, handle_cache.activity.onCreate, NULL);
if((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
activity_backlog = g_list_prepend(activity_backlog, _REF(activity_object));
if(recreate) // only allowed for toplevel, so we know for sure where in the stack it belongs
activity_backlog = g_list_append(activity_backlog, _REF(activity_object));
else
activity_backlog = g_list_prepend(activity_backlog, _REF(activity_object));
activity_update_current(env);
}
void activity_start(JNIEnv *env, jobject activity_object)
{
_activity_start(env, activity_object, false);
}
JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish(JNIEnv *env, jobject this, jlong window)
@@ -115,10 +147,16 @@ JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish(JNIEnv *env, jobje
activity_close(env, this);
if (removed_activity)
_UNREF(removed_activity);
if (activity_backlog == NULL)
if (activity_backlog == NULL && window)
gtk_window_close(GTK_WINDOW(_PTR(window)));
}
JNIEXPORT void JNICALL Java_android_app_Activity_nativeRecreateActivity(JNIEnv *env, jclass class, jobject activity)
{
_activity_start(env, activity, true);
}
JNIEXPORT void JNICALL Java_android_app_Activity_nativeStartActivity(JNIEnv *env, jclass class, jobject activity)
{
activity_start(env, activity);

View File

@@ -17,6 +17,14 @@ extern "C" {
JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish
(JNIEnv *, jobject, jlong);
/*
* Class: android_app_Activity
* Method: nativeRecreateActivity
* Signature: (Landroid/app/Activity;)V
*/
JNIEXPORT void JNICALL Java_android_app_Activity_nativeRecreateActivity
(JNIEnv *, jclass, jobject);
/*
* Class: android_app_Activity
* Method: nativeStartActivity

View File

@@ -404,7 +404,24 @@ public class Activity extends ContextWrapper implements Window.Callback {
return false;
}
public void recreate() {
try {
/* TODO: check if this is a toplevel activity */
Class<? extends Activity> cls = this.getClass();
Constructor<? extends Activity> constructor = cls.getConstructor();
Activity activity = constructor.newInstance();
activity.getWindow().native_window = getWindow().native_window;
System.out.println("activity.getWindow().native_window >"+activity.getWindow().native_window+"<");
nativeFinish(0);
nativeRecreateActivity(activity);
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
System.out.println("exception in Activity.recreate, this is kinda sus");
e.printStackTrace();
}
}
private native void nativeFinish(long native_window);
public static native void nativeRecreateActivity(Activity activity);
public static native void nativeStartActivity(Activity activity);
public static native void nativeOpenURI(String uri);
public static native void nativeShare(String text);