mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +00:00 
			
		
		
		
	Android: control activity re-creation
This commit is contained in:
		| @@ -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 */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sylvain
					Sylvain