In my phone when minimize aplicatoin then the Android always destroy activity. In Developer options I turn "Don't keep activities"
I use MVP.
When I minimize application the activity is ALWAYS destroy. Call method onDestroy().
OK.
But the question is: Is with activity also ALWAYS destroy presenter and model?
Yes. When your activity is destroyed, all the objects in that activity will also be destroyed.
You can recover the state of some objects by saving them into a Bundle before the activity gets destroyed and then retrieving them from the Bundle once the Activity is recreated.
Please, take a look at the documentation for the Activity Lifecycle.
Related
Having a bug which relate to the os kill/restore the activity (or the app?).
After some debug find if set don't keep activities and set Background process limit to no background process will cause different behavior.
saw this post, but it does not answer the question here.
Here is what observed:
In the application it will start dagger component and it maintains some app scope singleton object, and in activity A (the default launch activity) it will by user's action to launch activity B, in B it creates and hosts a fragment. There will be some data stored in the app scope singleton object to work with the fragment.
In case of only have the don't keep activities set, when minimize the app the activities onDestroy() is called, and when re-open the app it restores the last active activity (say the user opened the activity B, the B will be re-created with the fragment restored with the savedInstanceState). In this case the app scope singleton objects managed by the dagger are still alive, so the state is completely restored to what it was before minimized the app.
But if have both don't keep activities and set Background process limit to no background process, then when minimize the app, the activity's onDestroy() is not call (only call up to the onStop()).
The behavior change is at this time if re-open the app, it will start from application onCreate(), and recreate the dagger's component. So the state before minimize the app is not re-stored.
But the os seems still remembers the last activity is B and the B's
onCreate(savedInstanceState: Bundle?)
is called with savedInstanceState having the data saved when minimizing the app, so does B's fragment.
And it is a messed up, it has data from the savedInstanceState, but the app scope singleton objects are fresh ones that do not have the data to work with the ones from the savedInstanceState.
Anyone knows in this case where is the savedInstance saved, and why although the application seems to be recreated but still the last activity (not the launching activity) is re-stored?
The savedInstanceState bundle is explicitly intended to do as you describe. Regardless of whether a background activity is destroyed to conserve memory (e.g. "don't keep activities" is turned on) or whether an entire app process is killed to conserve memory (e.g. "background process limit" is zero), the framework will provide your app the ability to save state information into the savedInstanceState bundle and will subsequently return that state information to you in future calls to onCreate().
The only situation in which savedInstanceState will be null is the very first time your activity starts up. It doesn't matter whether your app's process is killed or not; if your activity is restored you will receive a non-null savedInstanceState bundle.
I have read the below statement from android document
Because onSaveInstanceState() is not guaranteed to be called, you
should use it only to record the transient state of the activity (the
state of the UI) — you should never use it to store persistent data
Since onSaveInstanceState() is not guaranteed to be called. How can we rely on that to save data? is there any particular situation where it won't be called?
As nPn has already given the link. Read below lines
(Reference :http://developer.android.com/reference/android/app/Activity.html)
One example of when onPause() and onStop() is called and not this
method is when a user navigates back from activity B to activity A:
there is no need to call onSaveInstanceState(Bundle) on B because
that particular instance will never be restored, so the system avoids
calling it. An example when onPause() is called and not
onSaveInstanceState(Bundle) is when activity B is launched in front of
activity A: the system may avoid calling onSaveInstanceState(Bundle)
on activity A if it isn't killed during the lifetime of B since the
state of the user interface of A will stay intact.
I would use onPause to persist object data.
See this activity life cycle diagram
http://developer.android.com/training/basics/activity-lifecycle/starting.html
Note: you should still use onSaveInstanceState() and onRestoreInstanceState(). These are your opportunity to save and restore the state of your application when for example the screen is rotated and the app is killed and then restarted.
When OS will completely forget the state about an Activity and all information relate to an Activity ( any records about an Activity) ?
In other words when it will make Bundle to be a new instance?
I found the below explanation but it does not explain this "Killing bundle" point?
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/Activity.java#Activity.onSaveInstanceState%28android.os.Bundle%29
Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(android.os.Bundle) or onRestoreInstanceState(android.os.Bundle) (the android.os.Bundle populated by this method will be passed to both).
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(android.os.Bundle) or onRestoreInstanceState(android.os.Bundle).
Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(android.os.Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(android.os.Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(android.os.Bundle) on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.
The default implementation takes care of most of the UI per-instance state for you by calling android.view.View.onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(android.os.Bundle)). If you override this method to save additional information not captured by each individual view, you will likely want to call through to the default implementation, otherwise be prepared to save all of the state of each view yourself.
If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().
There are many cases where this could occur:
Here is a small topic on reference mentioning different
use-cases about recreating activities.
If you want more control over the application life cycle:
Take a look a the application object for more information.
Personal advice:
I think you should not care about when/what, This is something the
android system will manage for you, your code should be optimized to
handle all usecases (when the bundle will be null or not). A bundle
should only be used to handle state-keeping, if you want to
persist data you should take a look at fileI/O, SQLlite or shared
preference.
Looking at the Activity Life Cycle diagram, I notice that onPause() and onStop() can both lead to the "process" being killed. This would require onCreate() to be called when the user wants to resume their application. The point being that onStop() is not necessarily called, nor is onDestroy(), but that onPause() may be the only event that the Activity may see. This being the case, onPause() must handle saving the application status so that the user can return back to it later, regardless of whether onStop() is called or not.
I can see onDestroy() being used to clean up Activity specific resources that would naturally be eliminated in a process kill action. Is there anything else that onDestroy() would be good for?
And what would onStop() be good for? Why would I want to override it for?
If I got your question right: It depends what you want to do with your application. Let's say you are programming application that uses GPS. In the onStop() which is called when the activity is no longer visible to the user, you can remove these requests. Or you can stop the some service if your application is running any. Or you can save preferences (not recommended, do it in onPause() instead), or you can close permanent connection to a server.....If I think of anything else, I'll add more...
If you have read the doc further, you'll see following:
Saving activity state
The introduction to Managing the Activity Lifecycle briefly mentions
that when an activity is paused or stopped, the state of the activity
is retained. This is true because the Activity object is still held in
memory when it is paused or stopped—all information about its members
and current state is still alive. Thus, any changes the user made
within the activity are retained in memory, so that when the activity
returns to the foreground (when it "resumes"), those changes are still
there.
However, when the system destroys an activity in order to recover
memory, the Activity object is destroyed, so the system cannot simply
resume it with its state intact. Instead, the system must recreate the
Activity object if the user navigates back to it. Yet, the user is
unaware that the system destroyed the activity and recreated it and,
thus, probably expects the activity to be exactly as it was. In this
situation, you can ensure that important information about the
activity state is preserved by implementing an additional callback
method that allows you to save information about the state of your
activity and then restore it when the the system recreates the
activity.
Summary: After completing onStop() Activity object is still alive in memory. And this will help the system to restore the activity.
Very basic example: consider you are showing your activity to user, and suddenly your friend calls you! Rest you can understand..
So now it it up to you that, which are the resources/objects/connections should be released on which event.
Another example would be to register and unregister a broadcast receiver.
Note that usually these things are placed in onResume and onPause, the difference is subtle though, onResume/onPause are called when the activity gets placed behind another activity, onStart/onStop are called when the activity is no longer visible in the screen.
I have a singleton in an activity. When I end my application (like pressing back button), and start it again after some time, the singleton is not recreated, but is holding previous state. Singleton is not destroyed if the application is destroyed? Do I have to null its static members in onDestroy() to avoid memory leak?
Thanks.
When you are 'ending' your activity it is just going in background. So state will be maintained. If you want to do something when the activity is not 'visible' you have to implement the onStop() method and not onDestroy().
Please refer how android manages stack of Tasks and activities. Also refer Activity Lifecycle.
Activity is stopped if it is
completely obscured by another
activity. It still retains all state
and member information. However, it is
no longer visible to the user so its
window is hidden and it will often be
killed by the system when memory is
needed elsewhere.