I have a strange behavior in my app when running in jelly bean 4.1.1 , when i start an Activity and press the back button to go back to the First Activity it re-create it by calling onCreate also , what i did also i handle the configuration change with the first activity so it won't recreated on configuration change but thats didnt make anything . !!!! why Activity life cycle in jelly bean have a strange behavior. You can see what i mean , just create a simple Android project and create two activity , navigate from the first one to activity to and press back button and see the logs onCreate on Activity 1 will be called !!!!
There is no guarentee that the OS won't kill your background Activities at any time if it determines that it needs the resources. Just a guess, but onCreate may get called in these cases because the system kills the first Activity before you get back to it.
Edit: http://developer.android.com/guide/components/activities.html#Lifecycle
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.
Here is another reference for you:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://developer.android.com/training/basics/activity-lifecycle/starting.html
In the first link:
The system may also destroy your activity if it's currently stopped and hasn't been used in a long time or the foreground activity requires more resources so the system must shut down background processes to recover memory.
...
However, if the system destroys the activity due to system constraints (rather than normal app behavior), then althought the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed. The saved data that the system uses to restore the previous state is called the "instance state" and is a collection of key-value pairs stored in a Bundle object.
Open Phone setting screen
click on developer option(if not present then press about phone 5-6 times)
In developer option in App category uncheck Do not keep Activities flag
Related
I'm wondering if Android system is able to kill the activity without the entire application process while the app is minimized. From Android documentation we know that onDestroy is only called when the activity is about to be destroyed and the systems guarantees to call this method whenever it is about to kill the activity, it will not be called only in case the entire application process is killed.
So, imagine such a situation - you send the app to the background(minimize) and after some time the os starts to run low on memory and decides to kill the activity, but since the app is currently suspended and cannot execute code it is not able to call its onDestroy method althought it is guaranteed that it will be called before every activity destruction.
So, this kind of reasoning gives me a thought that while the app is in the background os is only able to kill the entire process but not some specific activities. Is my reasoning correct, or did I miss something?
That's true: while the app is in the background os is only able to kill the entire process but not some specific activities.
Your reasoning is correct.
If the user navigates away from the activity/application (e.g. by pressing the home button) then the activity is said to be in the "Stopped" state. (States being "None-existent", "Stopped", "Paused" and "Resumed"). If android get low in memory and needs to kill some processes it will target those processes whose activities are in the "Stopped" state and it kill the whole process (not the activity). Furthermore, it will not be polite when doing so and therefore, will not call the activity's onDestroy() method.
Edit following comments about the confusion of saved state on process death:
If the activiy's process is killed, the system temporarily saves a set of settings outside the activity and using these settings, it recreates the activity the next time it is launched.
For example, just before moving to the "Stopped" state the system calls onSaveInstanceState(Bundle) on an activity that is not "finished" and saves this Bundle outside the activity. The system also does remember that it killed activity's process while it was not finished. Using these two along with other settings (saved outside the activity), the system recreates the activity.
If, However, the activity is finished (e.g. user presses the back button, swipes away the activity's card from the overview window, Activity.finish() is called explicitly, etc), onSaveInstanceState() is not called and the system doesn't save any settings to recreate the activity next time it's launched. It simply creates a fresh one.
This is good news, why? Becuase if it wasn't the case, the developer would have had to stash key state properties manually outside activities and reinstate them when activities are relaunched (that would've been a nightmare)
Since there's been much confusion on this issue, in large part due to the confusing state of the official docs in the past, here's what the docs say
at present:
The system never kills an activity directly to free up memory.
Instead, it kills the process in which the activity runs, destroying
not only the activity but everything else running in the process, as
well.
This as well as real world observation yields that the answer is no.
https://developer.android.com/guide/components/activities/activity-lifecycle#asem
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...
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
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,
Persistent
non persistent
if you mention for the activity in the manifest as
android:persistent="true"
and run the below use case
Start the APP
Press back or home button
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
Lets say an application is running with activity B is in top of the stack and activity A is the activity that has the launch intent defined in the manifest. Then my app goes in the background (not visible) and the system temporarily kills my application and brings it back up again.
At that point which activity does the system bring up first, activity A (launch intent defined in the manifest) or activity B ?
Also if the application is temporarily killed then does it restart right away or it might be dead for a while?
My application has a lot of dynamic state, it also logs in to a server, so when the application is temporarily killed then the state of my application can change during that time and when it is restarted I will again have to start my application and re-login and update all its state again. Is there any way this can be avoided?
Thanks.
Sure, If application is killed then it should start from launch activity. If there is login option, then you should keep remember me option too, so that if app is being killed you got the state of app and execute auto login if remember me is set otherwise just launch the app with login process.
I beg to differ from what #Keshav says. I think the Activity that was destroyed last is what is re-created and shown to the user. I base my belief based on what happens when the configuration of the device changes - the current activity is actually destroyed the same is re-created and it's not the very first activity that was launched.
As far as what you should do, guidelines when your app gets terminated or destroyed while it's in background, you have to refer to:
http://developer.android.com/guide/components/activities.html#SavingActivityState
You wrote:
Lets say an application is running with activity B is in top of the
stack and activity A is the activity that has the launch intent
defined in the manifest. Then my app goes in the background (not
visible) and the system temporarily kills my application and brings it
back up again.
The following happens:
A new process is created for your application
Your Application object is instantiated and onCreate() is called on it
An instance of ActivityB (the top activity on the task stack) is instantiated and onCreate() is called on it
Your root activity (ActivityA) will only be instantiated when (and if) ActivityB ends (is finished or the user presses the BACK button).
You cannot prevent Android from killing your app while it is in the background. However, you can determine that this has happened and react accordingly. The easiest way to do this is to have a static member variable *either in the root activity or in a custom Application class) that you set to true when the root activity is created and has performed its initialization. In onCreate() of ActivityB, check if this variable is set to true. If not, your app has been restarted, so you can now react. For example, you could just redirect the user back to the root activity and force start your application from the beginning. Or you could tell the user to wait while you reinitialize your application, etc.
I have an offline-online application, i found a strange issue in it, may be it is not, but i did'nt understand about it..
App requirement is that, if internet is available, even from starting app or from resuming, i call webservices and store data in sqlite, otherwise app stays in offline mode,
I have 2 activities, second activity contains an id, that i passes through intent (that point is important),
My Problem:
if i am in second activity, and internet is running, and i press home button , then this 2nd activity pauses, then stop which is a default behavior in android, i goto settings, turn wifi off, then press app icon again to get back in my app, here i got confused, i expect that my app now will be in onResume, but when i see in logcat its onCreated called and app
crashes, nullPointerException occurs, because this 2nd activity does not have that id, i passed through intent..
Note:
If i use recent app button to go to "settings", then come back again after turing wifi off, and repeat all this behavior, then working fine, its onResumes called not oncreate..
My Question
Why it is going in onCreate while i my expectation is to be onResume while i came back from app icon?
The NPE reason is clear, your second activity doesn't have the value and it crashes.
Why do you get different behavior then!?
It's because the launching intents are different. When you "task switch" Android is merely stopping your app but leaving it there (no guarantee) in case you want to switch back.
Going home (with home) is a clear indication that you want to leave the app, and although it will remain in memory and cached (as long as there is available memory), going back through the launcher (or App Icon as you call it) fires the LAUNCHER category (which goes to your Activity 1 first).
Take a look at this StackOverflow question (and answer) to better understand the consequences.
In any case, your problem is that your app must always be designed to resume in an inconsistent state and be able to recover. Android will kill your references, will destroy your variables and most likely send your app to hell overnight even if you have it running… if the phone goes on standby, chances are processes that aren't doing anything will be paused/stopped and likely killed.
Re-design your app so this is not a problem.
You say:
"I have 2 activities, second activity contains an id, that i passes
through intent (that point is important),"
Well, why not make it easier and have ONE activity and TWO fragments? Then use Fragment Arguments to pass the value?
Or why not store the value in the preferences and/or a local database and recover it during onCreate?
And also why not make it so that if Activity 2 doesn't have a value, it calls Activity 1 and closes itself (better than a crash, huh?).
Etc.
As you can see there are multiple things you should consider. All in all, never trust that your app will be alive, because it won't.
Once your activity's onStop gets called it's susceptible to be killed by the android system to collect resources for other apps which is what i think happened in your case.If it is killed, android will obviously call OnCreate when you get back to the activity.Check this for clarification. For experimenting you can try opening more than one apps from your recent apps and then return to your app. It may crash there too now.
You stated that you can see that the activitiy is stopped (onStop) if you go to the settings. That is the behaviour shown in the Android activity lifecycle. The counterpart for onStop is onCreate. So it does what the documentation tells us. Btw activities are paused if they are visible in some way and get stopped if they are not visible anymore. This would explain why your activity get paused. For further information read Managing the Activity Lifecycle. You can find a whole picture of the lifecycle here.
This type of behaviour can be seen when you change some system configurations like font type,font size or language. But turning wifi on/off won't destroy the app and recreate it again. Check http://developer.android.com/guide/topics/manifest/activity-element.html#config for more information
I got a main-activity, then it opened a new-activity. After putting it to background by clicking home button. If I killed the process using adb shell commands, then I reopen my app.
The new-activity is shown by default instead of starting from the first activity.
My question is that activity's life cycle is beyond its application process?
As the sample shows, even activity's application process is killed, the saved activity still is there. Is this correct? And will android system recycle the saved activities later?
If you reopen the app via the activities list, it will attempt to restart via the last open activity. It's a "feature" of Android that can be incredibly annoying (and frequently just wrong)- Android assumes every app can serialize its entire state when exited for later reopening. You either need to do that (via onSaveInstanceState and onRestoreInstanceState) or you need to catch when you're relaunched and explicity launch your main activity.
This shouldn't happen if you're relaunched via the app launcher, as that should always launch your specified activity.
Android remembers the state of recent tasks and activities. Android can kill your application's process at any time (if it is in the background). If your application was killed while in the background, Android remembers what activities were in the task and how they were started (Intents). If the user now returns to the task (either by selecting from the list of recent tasks, or by tapping the application's icon in the list of applications), Android will create a new process for the task and recreate the activity that was on the top of the stack (ie: the activity that was in front when the task was sent to the background). This allows users to open an applicaton, use it, leave it to do something else, and then return to the application where they left off.
In order for this to work properly, you must save and restore any necessary state (using onSaveInstanceState() and onRestoreInstanceState().
If a task goes to the background and is idle (unused) for some period of time (device manufacturers can change this, usually the value is something like 30 or 60 minutes), Android will reset the task. In this case, if the user returns to the task, the previous saved state will be ignored and the user will start from the beginning. However you can prevent this from happening by setting alwaysRetainTaskState="true" on the root (starting) activity.