Prevent activity from being destroyed as long as possible
Asked Answered
M

2

16

I have an app, a single activity app with fragments in it.

The usual use case for this app is, that you start it and put the phone away and every now and then, you get back to the phone and insert some data... It's a logging app, you are doing something and insert your results into the app...

I have the problem, that every now and then, my activity get's destroyed and is recreated with an empty bundle... (Most of the time this is not the case, but every now and then this happens...). My app sometimes starts a service, even this service is killed in this case...

This means, that the system has killed my app, does it? How can I avoid this?

I need to keep the user data and the current top fragments... And they are saved to the bundle and everything works as long as their states and the data get saved...

Btw., my activity is always the TOP ACTIVITY, only that the screen turns off often... I just want to keep my activity alive as long as possible until the user leaves it with the back button... Or to save the state reliably

IMPORTANT NOTE

onSaveInstance does not always work (it's not part of the lifecycle and therefore not guaranteed to be called)... it only works most of the time... I need a way to that works always... If android kills my app...

Mandle answered 4/3, 2014 at 9:46 Comment(3)
You can't block android from killing your app, you'd probably get killed too... I'm not sure how but you should be able to save your activity state and restore it when recreated.Microfilm
you should take care of your activity current state, have some states of activity which you could then serialize or save in shared preferences... and check on start of activityLowkey
You can prevent screen lock #3724134 and you can create an application class and put your static variables in it so that that will stay longerPapyrus
Q
9

don't keep your app in memory

You don't want to block Android from killing your app. What you want is to restore your app's state properly. Then the user will never notice the app has been destroyed and the user still gets the benefit of an app that was destroyed when not in use.

If you really want this use a wakelock. This will drain your users battery so I think twice before implementing this... Info at How do I prevent an Android device from going to sleep programmatically?

onSaveInstanceState explained

To do so check what information is needed in the bundle and persist that information with the onSaveInstanceState(bundle:Bundle) method so you can reuse it in onCreate(sameBundle:Bundle).

More information available from Google documentation at Save your Activity state and Restore your Activity State.

About Android Activity lifecycle

As stated by @prom85 in the comments below it's not guaranteed that the onSaveInstanceState method will be called because it's not part of the lifecycle. Workaround for this is using the onPause lifecycle hook to ensure your data is stored.

More information at Android: onSaveInstanceState not being called from activity

Queridas answered 4/3, 2014 at 10:3 Comment(5)
As I wrote in my post, it only happens SOMETIMES... So sometimes, onSaveInstance does not work and my activity will be recreated with an EMPTY bundle... Of course, most of the time this works... And I'm doing it like that already... I know, that android will kill my app because it thinks it is not needed anymore (screen is of, for example), but in my case, this is wrong... I thought about using a foreground service and bind it to my activity to solve my problem... But I would rather prefer a solution that allows my app to be killed but being restored correctly, always... Not only most times...Mandle
Then you should probably try to debug this. You can check the option form development options to always destroy activities to force the bundle being stored and then test with some different use cases of your app. Developer Options > Don't keep activities (at the bottom)Queridas
Actually, I did... This works, IF onSaveInstanceState is called... But their is no guarantee that it is called (as it's not part of the lifecycle)... That's my problem... I just thought, others may have already solved that somehow...Mandle
OK according to this SO answer you do have a point. The solution is to save it in the onPause method since that is part of the lifecycle. That's a solid work around. #12793569Queridas
I've read that (and I knew about this solution)... I'm still not sure, if the information is complete... Actually, I still don't know if I can be sure, that onSaveInstance is ALWAYS called, whenever the system destroys my activity... My life tests show, that I can't... But I'm not sure, if their may be a bug in my app or if I really can't be sure that this function is called... Do you know that? As written in your link, it seems like the function is skipped only, if the user presses back or the finish method is called... I'm not sure if that is correct...Mandle
M
6

I had a similar problem, I arrived at this post while searching for a solution, you have to play with the manifest to achieve this and also understand what exactly activity is, in Android eco system,

In Android activity is a task which has a pre defined work.

I dig a lot in the documentation, I found that, we can configure activity in two ways,

  1. Persistent
  2. non persistent

if you mention for the activity in the manifest as

android:persistent="true"

and run the below use case

  1. Start the APP
  2. Press back or home button
  3. you select the activity in the back stack again to bring it to front

Activity enters start -> pause -> stop - > resume , it does not get into onDestroy method.

if do not mention

android:persistent="true"

for the same use case

Activity enters start -> pause -> stop -> destroy, and if you select the activity from the back stack

Activity enters resume->create->start

If you want to run a service/task on activity start which keeps running when the app is in back stack, then you have to start that in the onCreate method, and kill them onDestroy by specifying your activity as persistent in manifest.

I hope my above solution might help others who arrive here for the same problem

Menefee answered 4/3, 2016 at 6:49 Comment(8)
Android Activities do not support this attribute. Its only available for Applications. Check developer.android.com/guide/topics/manifest/… for details.Alleluia
@Alleluia can you please check this link, developer.android.com/guide/topics/manifest/…Menefee
Correct, but thats the application and not an activity. This attribute can not be used to "configure an activity to be persistent". From the docs: "persistence mode is intended only for certain system applications". If your app is a system app, it will keep the app process running, not a single activity. You can also check this link for more information: groups.google.com/forum/#!topic/android-platform/nU0e3aoBlSYAlleluia
@Alleluia it works for activity also, please try it worked for meMenefee
The activity is running in the app context, it might of course also affect the lifecycle of your activities if the app process will be kept alive, but Android has introduced dedicated techniques for such use cases. (Services and Notifications to foreground the service). Check the quote of Dianne Hackborn (Android framework engineer) from the link posted above: "You really should not be using this in anything except core platform code. In the entire Android platform there is exactly one thing that uses it: the phone app ... (That is, very critical code for a phone.)"Alleluia
@Alleluia just because only phone APP uses this, how can you conclude that others should not use it, Dianne Hackborn's way is also a way, and my way is also a way. but intention is same. The owner of this post has asked for a way to do this, I have answered it. if you feel it is not a right fit you can ignore and post another answer, I don't agree that I am wrong, because this guy who has posted this question gives me a feeling that he has a need to create an APP like Phone APPMenefee
Because its written in the documentation. The solution is not blocking Android from managing the lifecycle of activities. The solution is to handle these kind of lifecycle steps and to recreate the activity correctly, even if it was destroyed. And this can be achieved by a clean implementation of a service with a foreground notification.Alleluia
@aravind.udayashankara this attribute is for <application> as was described in documentation you referred. Also in this documentation developer.android.com/guide/topics/manifest/… about <activity> the android:persistent attribute not exists.Carbrey

© 2022 - 2024 — McMap. All rights reserved.