Android Question ExitApplication -- A legitimate use case?

Charlie Burnham

Member
Licensed User
Hi, We have an app that is presented in a single-app kiosk launcher (Airdroid Biz) on devices that we own and control completely. There are multiple processes, but each process calls activity.finshed before going on the next one. On the final process, there is an "Exit App" button that does some file cleanup and then calls:
B4X:
Dim jo As JavaObject
jo.InitializeContext
jo.RunMethod("finishAffinity", Null)

The issue with that is that while the device (Android 10) returns to the launcher screen correctly, the next time you launch it from the launcher, it crashes immediately with the log error "java object not initialized (label)". I believe this is because the OS is using some (but not all) of the process code retained in memory to do the restart. If you try launching again, it works without error. So, it's not terrible, just ugly for the user.

When I changed to ExitApplication, we do not get this behavior and everything is fine. There is a brief moment when the native app tray is shown, but it doesn't matter because nothing is enabled there.

I believe it works because ExitApplication is well and truly getting rid of everything (except prior permissions) that is stored anywhere and would be part of a restart. But I am cautious about going against all the advice from the most expert people here never to use ExitApplication so I thought I would make this post. (I did not use Pages, by the way, because I started this project well before that wonderful thing existed, and I never need to return to earlier processes in my program flow.)
 

drgottjr

Well-Known Member
Licensed User
My recollection is that we were taught not to use ExitApplication because it went against android's vision of an application's normal life cycle. Whether or not something bad would happen depended on what was going on when you pulled the plug.

If you were interested, you could probably write a simple app (in B4A) which immediately called ExitApplication. then go look at the underlying java to see exactly which call(s) is/are being made. that might relieve some of your concerns.

have you tried finishandremovetask() as an alternative to finishAffinity()?

the situation isn't of particular interest to me, so i didn't spend much time researching, but a number of people seem to want to do what you're trying to do. at
link to SO here one reader posts a number of possible alternatives for you. the finishandremovetask() seemed promising after reading the documentation.
 
Upvote 0

Charlie Burnham

Member
Licensed User
Thank you for your suggestions. I did try finishandremovetask(), and it results in the same runtime error on restart via the launcher:

"java.lang.RuntimeException: java.lang.RuntimeException: Object should first be initialized (Label)".

The label referred to is the first call to a UI object in the Main activity, however the finishandremovetask() is in another activity. I already called activity.finish when I switched out of Main. It looks to me like Main is still assumed to be running by the OS when it is clicked on the launcher, but its object initializations no longer exist, and therefore the error. I suppose I could try something like conditionally initializing all the objects, but this seems wrong and tedious.

I haven't investigated yet, but I'm guessing ExitApplication actually does this:
Java:
android.os.Process.killProcess(android.os.Process.myPid());
 
Upvote 0

drgottjr

Well-Known Member
Licensed User
i'll add that call to my tool box, in the unlikely event i might need it.

if only a particular label needs initialization, that shouldn't be too tedious... you could try testing for its status before actually using it and see if that triggers yet another initialization error. also, you might want to check where you actually do initialize it. eg, if within an "if first then ..." block in activity.create, the initialization could be skipped when the app is relaunched. this is part of why we're not supposed to mess with the app's life cycle.
 
Upvote 0

OliverA

Expert
Licensed User
Upvote 0

Charlie Burnham

Member
Licensed User
It’s initialized by a layout load, not explicitly. There are actually 3 layouts, loaded in secession in the main activity. Perhaps this has something to do with it, however my understanding has been that everything should start over from the starter service entry point, all variables default or null, and not the state where activity.finished was called.
 
Upvote 0
Top