Why does singleton class survive Activity exit? - android

I have a Singleton class which I use with the one of the activities of my application.
When I exit the activity - which brings me back to the menu activity - and then reopen the activity I find that when I try to access the singleton it is still the same.
Surely it should have been destroyed with the Activity?
I saw the question here: living singleton, when activity end
but could not quite follow what they mean.
When I press the return button on my device (or use finish within the Activity itself) is the Activity kept alive for future use? If so, then that would explain it.

Surely it should have been destroyed with the Activity?
No.
When I press the return button on my device (or use finish within the Activity itself) is the Activity kept alive for future use?
The activity is not. The process is. Singletons are part of the virtual machine and will live as long as the process does. Exiting the last activity does not immediately terminate the process, so the singleton lives on... at least for a while.
Android will eventually terminate that process to free up memory for other apps. How quickly it will do that depends on what the user is doing, what apps are installed, phase of the moon, etc.

Related

Can one reuse a fragment after process has been killed?

Scenario:
An Android app has an Activity with a Fragment.
The user sends the app to the background by pressing the home key.
Two hours pass, the Android OS kills the process to free up resources.
The user switches back to the app through the Recent Apps List.
The onCreate method of the Activity will now find the existing Fragment by using fragmentManager.findFragmentByTag()* as best practice cites. Yet, adding this old fragment to the activity will not make the fragment render. I'm unsure if I'm doing something wrong, or this is simply not a supported use case for reusing old fragments.
Must I implement special handling of this scenario (i.e. new up the Fragment instead of reusing the old)? If so, what is the best practice of detecting that the process has been killed and relaunched in onCreate?
edit 1: *) I am testing this by using DDMS to kill the process. This might not emulate the OS' way terminating a process correctly, as for instance onDestroy() is not called. Does anoyone know if the old fragments are disposed from the FragmentManager when onDestroy() is invoked by the OS? If this is the case, this question is moot.
No, You can't reuse a Fragment once the process is killed. Once the process is killed, you app no longer exists on Android main thread, hence a new instance of the activity has to be launched.
Your app starts with an your main activity as in Manifest file, and loads corresponding views and fragments. Please go through the Activity Lifecycle of the Android, to know more about it.
This teaches you how to maintain your activity run in background and when not in use:http://developer.android.com/training/basics/activity-lifecycle/index.html

What happens when all activities of an application finishes?

Scenario:
I've four activities in my Android Application, lets say A, B, C and D. There is one Constants.java class in the app which extends Application class in order to maintain global application state. The Constants class have all the constants variables of the app. The activity flow is like this A-->B-->C-->D. When back button is being pressed from Activity A, I'm calling finish() method which will finishes the activity A and closes the application. After that if I'm opening the app from all apps, there is a variable in Constants.java whose value persists from the last launch. The same thing is not happening when I'm doing System.exit(10) followed by Process.killProcess(Process.myPid()) from activity A(on back pressed).
Questions:
Will finishing all activities by calling finish() of each activity will close the Application(Its process)?
How the value of a variable persists even if its all activities are finished(closed)?
Is it fair to call System.exit(10) followed by Process.killProcess(Process.myPid()) for exiting the application?
Update:
How can I clear the application constants on exit of the application(Back press of the HomeActivity)?
1) No, Android does not guarantee so. It's up to the OS to decide whether to terminate the process or not.
2) Because the Activity instance still lives in the Dalvik VM. In Android each process has a separate Dalvik VM.
Each process has its own virtual machine (VM), so an application's
code runs in isolation from other applications.
When you call finish() this doesn't mean the Activity instance is garbage collected. You're telling Android you want to close the Activity (do not show it anymore). It will still be present until Android decides to kill the process (and thus terminate the DVM) or the instance is garbage-collected.
Android starts the process when any of the application's components
need to be executed, then shuts down the process when it's no longer
needed or when the system must recover memory for other applications.
3) I wouldn't do so unless you have some very strong reason. As a rule of thumb, you should let Android handle when to kill your application, unless there's something in your application state that requires an application reset when it loses focus.
Quotes source
Will finishing all activities by calling finish() of each activity will close the Application(Its process)?
No, it should not. This is because Activities are not the only component of an app. Services, BroadcastReceivers can still run without a UI. By keeping the Application process running while it can, Android ensures faster response to the user opening the app again, or faster launching of Services etc. as the Application instance doesn't need to be recreated.
Your process will only be terminated if you or another app explicitly kill it, or the system kills it to free resources.
How the value of a variable persists even if its all activities are finished(closed)?
Your variable is in the Application class, which follows a Singleton model, and hence your value will persist until the entire app process is killed.
Additionally, finish() only calls onDestroy(), which is not a deconstructor, as explained here. So even Activity variables may persist after finish has been called, as your instance is still kept around until Android feels the need to destroy it, or your process is killed.
Is it fair to call System.exit(10) followed by Process.killProcess(Process.myPid()) for exiting the application?
While this will kill the app, it is not recommended. See this question for a variety of reasons for that.
for your Update:
How can I clear the application constants on exit of the application(Back press of the HomeActivity)?
Override onBackPressed inside your HomeActivity and before call super.onBackPressed() clear all the variable. If you have a setter for a String located inside your Application subclass:
#Override
public void onBackPressed() {
getApplication().setMyString(null);
super.onBackPressed();
}
if you have plenty states to clear you can write a method wich reset all the fields and call it:
#Override
public void onBackPressed() {
getApplication().clearAllMyFields();
super.onBackPressed();
}
Of course those field have not to be marked as final or static final
Android will keep the process until it needs to reclaim the process memory. That way, if the user immediately returns to your application, your application will appear quicker.
The value will persist until the application is killed.
Should not using System.exit(10) followed by Process.killProcess(Process.myPid()) for exiting the application?
You should really think about not exiting the application. This is not how Android apps usually work.

About the life cycle of an android component

First of all, I'm new in android developing...
I had read some article in android API guide and feel confused about the component life cycle with the hosting process.
Here is my understanding:
Android system may kill some activities in a process or the whole process in low memory situations,which means there is a possibility that a started activity may die, but process still alive.
If a service is started and not call any stop method, when in extreme low memory, this service is killed by system with its hosting process, not just the service itself, means this circumstance should not occur:service is killed by system, but hosting process still alive.
When an app starts, the user navigates activity1 -> activity2 -> activity3 and none of them call finish(). Next, the user navigates to another app's activity and plays with it so long that the former app process is killed by the system. Now the user navigate back to activity3 in the back-tracking stack, what will happens? The former app process restarts with only activity3 recreate?
Anything wrong ?
There is no need to switch to another app's activity: from the moment that you leave the first activity to go to the second activity; there is a clear possibility that the first activity might have been destroyed when you return on it from the second activity (back-tracking) and when you go to a third one, either the first one, the second or both of them can be possibly destroyed in the mean time. In fact, you don't even to leave an activity to see it destroyed; as this will automatically happen simply if you switch from the portrait mode to the landscape mode and vice-versa by rotating the device.
When you return to an activity, the onRestart() function will be called if the activity has not been destroyed in the mean time. If it has, the "onCreate(Bundle savedInstanceState)" will be called instead but with the argument "savedInstanceState" set to a non-null value (ie, it will point toward a valid Bundle object) if you have took the precaution of saving the current state of the activity in the "onSaveInstanteState(Bundle outState)" function when the activity has entered the process of being destroyed by the system. The system will always call this function before destroying an activity when this one need to be restored later for back-tracking. Of course, it won't be called after a call to finish() because this will also remove the activity from the back-tracking stack.
Finally, in Android, the coupling between activities in the same application is very loose. When it comes to the use of resources, there is not much of a difference between switching to an activity from the same application or from another application. In many ways, activities will behave like if there were all fully independant applications when it comes to running. This is why you always need to use an intent to start an activity; even when it is from the same application.
Based on my understanding ...
In android during low memory situations, first activities would be removed from memory where the onDestroy method gets called.
This is not the case always. It depends on how the service is started i.e whether from onStart or through Binding the service with a component.
Once the former app process is killed, then when the user launches the application, he will be taken to activity 1. Launching the activity in same task or different task depends on launch modes used (single task, etc)

Android multitaksing

I am seeking short characteristic of Android Multitasking. I have found, that when you minimize Android application, it is ended and it's process remains on the background. When user wants to reuse his app, this process alive it's application. User will be at the same state, when he left (if there was enough memory while working with it), or it will be loaded from scratch, because there was no free RAM for other work and Android exited this process. Am I right? Everywhere there are articles with 20 pages and more about Android multitaksing. I need to know key points because I am lost in a such long artices.
Thanks
Short Answer: Yes. If your app can live in memory despite being 'closed' then it will stay in RAM and processing will continue when you click on it again. Otherwise it will be restarted and you will get an onResume().
Long Answer: Please just read the Activity Lifecycle:
When Android activity is covered by other windows it will enter into paused state and method onPause will be called. It may also me destroyed by OS and then onDestroy will be called. You have very little control over it and can't expect your application to come back up with the same state. However, when activity is brought up again to foreground in will go through steps of onCreate and onPause. Those methods can be used to restore its state.
Here you can find nice diagrams describing Activity lifecycle. Similar but slightly different lifecycle is applicable to service.
http://developer.android.com/reference/android/app/Activity.html
Android activities are the main visible screens that user see while the application is running. If you close the screen or switch to another application, the current activity is put to hibernate and you can save the state with
Activity.onSaveInstanceState(Bundle bundle)
After your activity gets the control back, you can restore the state with
Activity.onRestoreInstanceState(Bundle bundle)
Note that you need to be careful not to store any context references within the activities and related classes as the activity and thus context has changed between pause and resume. Instead, you should always pass the current activity as the active context to avoid having exceptions from invalid context.

living singleton, when activity end

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.
Take a look at the attached picture.
Just because the application is no longer visible doesn't mean it has shut down.
I'd have to see code to give you a definitive answer, but before you assume the application is gone, kill the application manually with a task killer or the built-in application manager. Then, see if when you restart it, the singleton is reinitialized.
If killing it manually fixes the problem, you may want to 'uninitialize' the singleton in "onStop()" if you want it to go away when the application leaves the foreground. You can also try adding an "exit" menu function?
If you give me an update either with code or whether the task killer works, I'll see if I can give you a better answer.
(sorry I can't just attach the picture--I'm a new user)
http://developer.android.com/images/activity_lifecycle.png

Categories

Resources