The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
How to end SDLActivity correctly
Edition Chamäleon


Joined: 03 Nov 2016
Posts: 16
Location: Düsseldorf, Germany
Hello World,

I'm trying to find a way to end my android App correctly, which is native and based on SDLActivity.
Ending the hard way via homebutton always works. But now I want to implement an exitbutton in my app which enables the user to end it more elegant.

So when the button has been triggered, I'm cleaning all up, killing all my singletons and leave my mainloop. Then I "return 0" out of "int main(int argc, char* argv[])". That's all on native side.
The app ends seemingly. But when I press homebutton on my device, I can see that the app is still there on standby. Shocked
If I try to open it, it crashes and there comes the black screen with "... has been stoped".
And only then the app is really gone.

This is not elegant. Confused

Can anyone help me ?

Thanx in advance,

Michael
How to end SDLActivity correctly
hardcoredaniel
Guest

Hi,

Android apps are not automatically unloaded even after the onDestroyed() callback, e.g. when they are in the destroyed lifecycle state. They will only be removed from memory if more recently started apps would require memory themselfes. This is probably intentional to have a faster re-start of apps.

As a consequence, all code needs to be "re-startable", e.g. not relying on static initialization which is only executed when the code/the library is initially loaded into memory. (There was also a posting to this list where a method is described that removes this requirement from native code, but it means more effort to place all your code into an additional native library which you unload upon onDestroy())

I guess that in your case the app successfully enters the "destroyed" state, but upon restart sth. goes wrong because some code does not work when being called a 2nd time. You should see that in the stacktrace when your app crashes.

Regards,

Daniel



---------- Původní zpráva ----------
Od: Edition Chamäleon
Komu:
Datum: 14. 12. 2016 16:46:35
Předmět: [SDL] How to end SDLActivity correctly
Quote:
Hello World,

I'm trying to find a way to end my android App correctly, which is native and based on SDLActivity.
Ending the hard way via homebutton always works. But now I want to implement an exitbutton in my app which enables the user to end it more elegant.

So when the button has been triggered, I'm cleaning all up, killing all my singletons and leave my mainloop. Then I "return 0" out of "int main(int argc, char* argv[])". That's all on native side.
The app ends seemingly. But when I press homebutton on my device, I can see that the app is still there on standby.
If I try to open it, it crashes and there comes the black screen with "... has been stoped".
And only then the app is really gone.

This is not elegant.

Can anyone help me ?

Thanx in advance,

Michael

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Edition Chamäleon


Joined: 03 Nov 2016
Posts: 16
Location: Düsseldorf, Germany
I'd like to add some logcat:

on 03.004 my native is ending "int main" and SDLActivity jumps in "handleNativeExit()" (sounds and feels right)
but on 03.014 it jumps in "onPause()" Shocked (why is that?)
on 03.404 the app is seemingly closed ( but as I wrote it's only seemingly = the app is still standby )

using homebutton to see standby apps and so on .. is all after 03.404



Code:
12-14 17:02:03.004: V/Mw(3679): I: 342 ,T: 0 > MwAppUpdater::~MwAppUpdater  end.
12-14 17:02:03.004: V/SDL(3679): class SDLSurface public void surfaceChanged : Native thread finished +++++++++++++++++++++++++++++++++++++++++++++
12-14 17:02:03.004: V/SDL(3679): SDLActivity.java public static void handleNativeExit() reached
12-14 17:02:03.014: V/Mw(3679): ECActivity onPause() reached
12-14 17:02:03.014: V/SDL(3679): SDLActivity.java protected void onPause() reached
12-14 17:02:03.014: V/SDL(3679): SDLActivity.java public static void handleNativeExit() end.
12-14 17:02:03.014: V/SDL(3679): SDLActivity.java public static void handlePause() jumping to native SDLActivity.nativePause().
12-14 17:02:03.014: V/SDL(3679): nativePause()
12-14 17:02:03.014: V/SDL(3679): SDLActivity.java public static void handlePause() returning from native SDLActivity.nativePause().
12-14 17:02:03.014: I/SensorManagerA(3679): getReportingMode :: sensor.mType = 1
12-14 17:02:03.024: D/SensorManager(3679): unregisterListener ::   
12-14 17:02:03.024: V/SDL(3679): SDLActivity.java protected void onPause() end.
12-14 17:02:03.024: V/Mw(3679): ECActivity onPause() end
12-14 17:02:03.204: V/SDL(3679): surfaceDestroyed()
12-14 17:02:03.364: W/IInputConnectionWrapper(3679): showStatusIcon on inactive InputConnection
12-14 17:02:03.404: V/Mw(3679): ECActivity onDestroy() reached
12-14 17:02:03.404: V/SDL(3679): SDLActivity.java protected void onDestroy() reached
12-14 17:02:03.404: V/SDL(3679): SDLActivity.java protected void onDestroy() end.
12-14 17:02:03.404: V/Mw(3679): ECActivity onDestroy() end
12-14 17:02:21.614: V/Mw(3679): ECActivity.java protected void onCreate(Bundle savedInstanceState) reached
12-14 17:02:21.614: V/SDL(3679): SDLActivity.java protected void onCreate(Bundle savedInstanceState) reached with singleton:null
12-14 17:02:21.624: V/SDL(3679): SDLActivity.java protected void onCreate(Bundle savedInstanceState) end.
12-14 17:02:21.624: V/Mw(3679): ECActivity.java private void initMw() reached
12-14 17:02:21.624: V/Mw(3679): Java_org_libsdl_app_SDLActivity_SendAssManToNative reached
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18621 >  native routine for assetmanagertransfere reached
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18621 > JNICALL Java_org_libsdl_app_SDLActivity_SendAssManToNativ : loaded assetmanager
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18621 > Trying to jump into TAssReader and set AAssetManager mgr
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18621 > Loaded Assetmanager in nativ MwAndroidAssetReader!
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18621 >  The Assetmanager is set in TAssReader
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > Java_de_editionchamaeleon_ECApp_ECActivity_SendScreenSizeToNative: Setting ScreenSize in NativCode : 960 , 540
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::MwAppConst() reached
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::MwAppConst() init MwGELib version 1.0.1
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::CalcLevelSize() reached
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::CalcLevelSize() end
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::MwAppConst() end
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::SetDeviceScreenSize reached with 960,540
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::CalcBestScaledScreenSize reached
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::CalcBestScaledScreenSize end
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18622 > MwAppConst::SetDeviceScreenSize end
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18623 > Java_de_editionchamaeleon_ECApp_ECActivity_SetLanguage: result: de
12-14 17:02:21.624: V/Mw(3679): I: 342 ,T: 18623 > Java_de_editionchamaeleon_ECApp_ECActivity_SetLanguage: Setting TCons::InitLanguage: de
12-14 17:02:21.624: V/Mw(3679): ECActivity.java private void initMw() end
12-14 17:02:21.624: V/Mw(3679): ECActivity.java protected void onCreate(Bundle savedInstanceState) end.
12-14 17:02:21.624: V/SDL(3679): SDLActivity.java protected void onResume() reached
12-14 17:02:21.624: V/SDL(3679): SDLActivity.java public static void handleResume()  reached
12-14 17:02:21.624: V/SDL(3679): SDLActivity.java public static void handleResume()  end.
12-14 17:02:21.624: V/SDL(3679): SDLActivity.java protected void onResume() end.
12-14 17:02:21.664: V/SDL(3679): surfaceCreated()
12-14 17:02:21.664: V/SDL(3679): surfaceChanged()
12-14 17:02:21.664: V/SDL(3679): pixel format RGB_565
12-14 17:02:21.664: V/SDL(3679): Window size:960x540
12-14 17:02:21.664: I/SensorManagerA(3679): getReportingMode :: sensor.mType = 1
12-14 17:02:21.674: D/SensorManager(3679): registerListener :: 0, MPU-6K Accelerometer, 20000, 0, 
12-14 17:02:21.674: I/SDL(3679): SDL_Android_Init()
12-14 17:02:21.674: I/SDL(3679): SDL_Android_Init() finished!
12-14 17:02:21.674: V/Mw(3679): I: 342 ,T: 18673 > Reached main()!
12-14 17:02:21.674: V/Mw(3679): I: 342 ,T: 18673 >  MwAppUpdater::InitGame  reached.
12-14 17:02:21.674: A/libc(3679): Fatal signal 11 (SIGSEGV) at 0x400eb1c8 (code=2), thread 3751 (SDLThread)
12-14 17:02:21.704: V/SDL(3679): SDLActivity.java public static void handleResume()  reached
12-14 17:02:21.704: V/SDL(3679): SDLActivity.java public static void handleResume()  end.
Edition Chamäleon


Joined: 03 Nov 2016
Posts: 16
Location: Düsseldorf, Germany
Hi Daniel,

thank you for your fast answer. Resuming my app, when it is paused via homebutton works fine. But the exitbutton that I want to implement should kill the app complete and shut it down.
As I wrote I'm killing all of my native app, when the exitbutton is triggered by the user, therefore it isn't restartable anymore. Is that a wrong way?
Michael
How to end SDLActivity correctly
hardcoredaniel
Guest

You cannot completely "exit" an Activity on Android (like on Windows or other OSes where exit() resp. return from main unloads the program from memory). Android will decide for itself whether and when to remove an Activity from memory. Think of it like files that an OS will cache in memory for performance reasons - Android does the same with Activities.

An Activity being in the "destroyed" state should however not behave differently when started, compared to an Activity that has not been started before. And yes, Android apps should always be restartable, because you'll never know whether the app was removed from memory in the meantime. This might need special attention (like no static initialization in native code, and SDLActivity re-initializing some fields upon onDestroy() already, which looks strange but is correct).



---------- Původní zpráva ----------
Od: Edition Chamäleon
Komu:
Datum: 14. 12. 2016 17:15:31
Předmět: Re: [SDL] How to end SDLActivity correctly
Quote:
Hi Daniel,

thank you for your fast answer. Resuming my app, when it is paused via homebutton works fine. But the exitbutton that I want to implement should kill the app complete and shut it down.
As I wrote I'm killing all of my native app, when the exitbutton is triggered by the user, therefore it isn't restartable anymore. Is that a wrong way?
Michael

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
How to end SDLActivity correctly
SiPlus


Joined: 06 Feb 2015
Posts: 13
You can use exit() the same way as you use it on other OSes, and it will kill all activities and services currently running in the calling process (by default, there is one process for all activities and services, but using the android:process attribute in AndroidManifest.xml you can put different components of your application into different processes - but you won't need it most of the time).

If you're making a game with the traditional singleton lifecycle, it's perfectly fine to use exit() and other per-process things such as global variables, while using the singleTask launch mode to maintain only one activity for your game (the activity basically being the drawing surface and input interface). It's simply not possible to respect the Android lifecycle with everything being local to activity and saved/restored during configuration changes (mostly you can even skip configuration changes at all using the android:configChanges attribute, and/or only handle special cases such as font size changes) when you have a game any more complex than Pong or whatever anyway.

It's just not how you should design regular apps. Games rarely need the activity-based interaction model, so the singleton architecture is both acceptable and a common practice.

SDL is designed in the way that allows having multiple activities and services of the same application running simultaneously, so it doesn't kill the process by itself, but rather notifies the application code that an exit was performed. So it's the application's responsibility to handle the quit event as it needs it to be handled - and if you need to kill the whole process, nothing can stop you from killing the whole process.

On 14/12/2016 20:28, hardcoredaniel wrote:

Quote:
You cannot completely "exit" an Activity on Android (like on Windows or other OSes where exit() resp. return from main unloads the program from memory). Android will decide for itself whether and when to remove an Activity from memory. Think of it like files that an OS will cache in memory for performance reasons - Android does the same with Activities.

An Activity being in the "destroyed" state should however not behave differently when started, compared to an Activity that has not been started before. And yes, Android apps should always be restartable, because you'll never know whether the app was removed from memory in the meantime. This might need special attention (like no static initialization in native code, and SDLActivity re-initializing some fields upon onDestroy() already, which looks strange but is correct).



---------- Původní zpráva ----------
Od: Edition Chamäleon
Komu:
Datum: 14. 12. 2016 17:15:31
Předmět: Re: [SDL] How to end SDLActivity correctly
Quote:
Hi Daniel,

thank you for your fast answer. Resuming my app, when it is paused via homebutton works fine. But the exitbutton that I want to implement should kill the app complete and shut it down.
As I wrote I'm killing all of my native app, when the exitbutton is triggered by the user, therefore it isn't restartable anymore. Is that a wrong way?
Michael

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
EternalLands


Joined: 01 Dec 2016
Posts: 16
I always use exit(1); when I want to terminate the app. It works quite well.
Return after the main loop doesn't work well, sometimes it will crash the next time the app is started.