Android: control activity re-creation
parent
2e6c48dcb4
commit
dfd80f3d76
|
@ -29,3 +29,4 @@ General:
|
||||||
* Added SDL_GetRenderVSync() to get vsync of the given renderer
|
* Added SDL_GetRenderVSync() to get vsync of the given renderer
|
||||||
* Added SDL_PlayAudioDevice() to start audio playback
|
* Added SDL_PlayAudioDevice() to start audio playback
|
||||||
* Added SDL_ConvertAudioSamples() to convert audio samples from one format to another
|
* Added SDL_ConvertAudioSamples() to convert audio samples from one format to another
|
||||||
|
* Added SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY hint to control re-creation of Android SDL activity.
|
||||||
|
|
|
@ -221,6 +221,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
|
|
||||||
// This is what SDL runs in. It invokes SDL_main(), eventually
|
// This is what SDL runs in. It invokes SDL_main(), eventually
|
||||||
protected static Thread mSDLThread;
|
protected static Thread mSDLThread;
|
||||||
|
protected static boolean mSDLMainFinished = false;
|
||||||
|
protected static boolean mActivityCreated = false;
|
||||||
|
|
||||||
protected static SDLGenericMotionListener_API12 getMotionListener() {
|
protected static SDLGenericMotionListener_API12 getMotionListener() {
|
||||||
if (mMotionListener == null) {
|
if (mMotionListener == null) {
|
||||||
|
@ -324,6 +326,24 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
Log.v(TAG, "onCreate()");
|
Log.v(TAG, "onCreate()");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
/* Control activity re-creation */
|
||||||
|
if (mSDLMainFinished || mActivityCreated) {
|
||||||
|
boolean allow_recreate = SDLActivity.nativeAllowRecreateActivity();
|
||||||
|
if (mSDLMainFinished) {
|
||||||
|
Log.v(TAG, "SDL main() finished");
|
||||||
|
}
|
||||||
|
if (allow_recreate) {
|
||||||
|
Log.v(TAG, "activity re-created");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "activity finished");
|
||||||
|
System.exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mActivityCreated = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.currentThread().setName("SDLActivity");
|
Thread.currentThread().setName("SDLActivity");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -950,6 +970,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||||
public static native void nativePermissionResult(int requestCode, boolean result);
|
public static native void nativePermissionResult(int requestCode, boolean result);
|
||||||
public static native void onNativeLocaleChanged();
|
public static native void onNativeLocaleChanged();
|
||||||
public static native void onNativeDarkModeChanged(boolean enabled);
|
public static native void onNativeDarkModeChanged(boolean enabled);
|
||||||
|
public static native boolean nativeAllowRecreateActivity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called by SDL using JNI.
|
* This method is called by SDL using JNI.
|
||||||
|
@ -1902,6 +1923,7 @@ class SDLMain implements Runnable {
|
||||||
if (SDLActivity.mSingleton != null && !SDLActivity.mSingleton.isFinishing()) {
|
if (SDLActivity.mSingleton != null && !SDLActivity.mSingleton.isFinishing()) {
|
||||||
// Let's finish the Activity
|
// Let's finish the Activity
|
||||||
SDLActivity.mSDLThread = null;
|
SDLActivity.mSDLThread = null;
|
||||||
|
SDLActivity.mSDLMainFinished = true;
|
||||||
SDLActivity.mSingleton.finish();
|
SDLActivity.mSingleton.finish();
|
||||||
} // else: Activity is already being destroyed
|
} // else: Activity is already being destroyed
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,13 @@ You should not use the SDL renderer API while the app going in background:
|
||||||
GL context is restored, and the SDL renderer API is available (unless you
|
GL context is restored, and the SDL renderer API is available (unless you
|
||||||
receive SDL_EVENT_RENDER_DEVICE_RESET).
|
receive SDL_EVENT_RENDER_DEVICE_RESET).
|
||||||
|
|
||||||
|
Activity lifecyle
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
You can control activity re-creation (eg. onCreate()) behaviour. This allows to keep
|
||||||
|
or re-initialize java and native static datas, see SDL_hints.h:
|
||||||
|
- SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY
|
||||||
|
|
||||||
Mouse / Touch events
|
Mouse / Touch events
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,19 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
|
#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief A variable to control whether SDL activity is allowed to be re-created.
|
||||||
|
* If so, java static datas and static datas from native libraries remain with their current values.
|
||||||
|
* When not allowed, the activity terminates with exit(0) to be fully re-initialized afterward.
|
||||||
|
*
|
||||||
|
* The variable can be set to the following values:
|
||||||
|
* "0" - Not allowed. (default)
|
||||||
|
* "1" - Allowed.
|
||||||
|
*
|
||||||
|
* The value of this hint is used at runtime, so it can be changed at any time.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY "SDL_ANDROID_ALLOW_RECREATE_ACTIVITY"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Specify an application name.
|
* \brief Specify an application name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "../../joystick/android/SDL_sysjoystick_c.h"
|
#include "../../joystick/android/SDL_sysjoystick_c.h"
|
||||||
#include "../../haptic/android/SDL_syshaptic_c.h"
|
#include "../../haptic/android/SDL_syshaptic_c.h"
|
||||||
#include "../../hidapi/android/hid.h"
|
#include "../../hidapi/android/hid.h"
|
||||||
|
#include "../../SDL_hints_c.h"
|
||||||
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <android/configuration.h>
|
#include <android/configuration.h>
|
||||||
|
@ -166,6 +167,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
||||||
JNIEnv *env, jclass cls,
|
JNIEnv *env, jclass cls,
|
||||||
jint requestCode, jboolean result);
|
jint requestCode, jboolean result);
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeAllowRecreateActivity)(
|
||||||
|
JNIEnv *env, jclass jcls);
|
||||||
|
|
||||||
static JNINativeMethod SDLActivity_tab[] = {
|
static JNINativeMethod SDLActivity_tab[] = {
|
||||||
{ "nativeGetVersion", "()Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetVersion) },
|
{ "nativeGetVersion", "()Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetVersion) },
|
||||||
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
|
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
|
||||||
|
@ -197,7 +201,8 @@ static JNINativeMethod SDLActivity_tab[] = {
|
||||||
{ "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
|
{ "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
|
||||||
{ "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
|
{ "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
|
||||||
{ "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) },
|
{ "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) },
|
||||||
{ "nativePermissionResult", "(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) }
|
{ "nativePermissionResult", "(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) },
|
||||||
|
{ "nativeAllowRecreateActivity", "()Z", SDL_JAVA_INTERFACE(nativeAllowRecreateActivity) },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Java class SDLInputConnection */
|
/* Java class SDLInputConnection */
|
||||||
|
@ -375,6 +380,9 @@ static void Internal_Android_Destroy_AssetManager(void);
|
||||||
static AAssetManager *asset_manager = NULL;
|
static AAssetManager *asset_manager = NULL;
|
||||||
static jobject javaAssetManagerRef = 0;
|
static jobject javaAssetManagerRef = 0;
|
||||||
|
|
||||||
|
/* Re-create activity hint */
|
||||||
|
static SDL_AtomicInt bAllowRecreateActivity;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
Functions called by JNI
|
Functions called by JNI
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -525,6 +533,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
register_methods(env, "org/libsdl/app/SDLAudioManager", SDLAudioManager_tab, SDL_arraysize(SDLAudioManager_tab));
|
register_methods(env, "org/libsdl/app/SDLAudioManager", SDLAudioManager_tab, SDL_arraysize(SDLAudioManager_tab));
|
||||||
register_methods(env, "org/libsdl/app/SDLControllerManager", SDLControllerManager_tab, SDL_arraysize(SDLControllerManager_tab));
|
register_methods(env, "org/libsdl/app/SDLControllerManager", SDLControllerManager_tab, SDL_arraysize(SDLControllerManager_tab));
|
||||||
register_methods(env, "org/libsdl/app/HIDDeviceManager", HIDDeviceManager_tab, SDL_arraysize(HIDDeviceManager_tab));
|
register_methods(env, "org/libsdl/app/HIDDeviceManager", HIDDeviceManager_tab, SDL_arraysize(HIDDeviceManager_tab));
|
||||||
|
SDL_AtomicSet(&bAllowRecreateActivity, SDL_FALSE);
|
||||||
|
|
||||||
return JNI_VERSION_1_4;
|
return JNI_VERSION_1_4;
|
||||||
}
|
}
|
||||||
|
@ -731,6 +740,21 @@ typedef int (*SDL_main_func)(int argc, char *argv[]);
|
||||||
|
|
||||||
static int run_count = 1;
|
static int run_count = 1;
|
||||||
|
|
||||||
|
static void SDLCALL SDL_AllowRecreateActivityChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||||
|
{
|
||||||
|
if (SDL_GetStringBoolean(hint, SDL_FALSE)) {
|
||||||
|
SDL_AtomicSet(&bAllowRecreateActivity, SDL_TRUE);
|
||||||
|
} else {
|
||||||
|
SDL_AtomicSet(&bAllowRecreateActivity, SDL_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeAllowRecreateActivity)(
|
||||||
|
JNIEnv *env, jclass jcls)
|
||||||
|
{
|
||||||
|
return SDL_AtomicGet(&bAllowRecreateActivity);
|
||||||
|
}
|
||||||
|
|
||||||
/* Start up the SDL app */
|
/* Start up the SDL app */
|
||||||
JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, jstring library, jstring function, jobject array)
|
JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, jstring library, jstring function, jobject array)
|
||||||
{
|
{
|
||||||
|
@ -739,6 +763,9 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls,
|
||||||
void *library_handle;
|
void *library_handle;
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeRunMain() %d time", run_count);
|
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeRunMain() %d time", run_count);
|
||||||
|
if (run_count == 1) {
|
||||||
|
SDL_AddHintCallback(SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY, SDL_AllowRecreateActivityChanged, NULL);
|
||||||
|
}
|
||||||
run_count += 1;
|
run_count += 1;
|
||||||
|
|
||||||
/* Save JNIEnv of SDLThread */
|
/* Save JNIEnv of SDLThread */
|
||||||
|
|
Loading…
Reference in New Issue