Activity is getting destroyed while pressing the home button - android

In my application, when I press the home button the activity is going to onDestroy(). It suppose to be called onPause() method only right?
Why it is happening so?

also check that you don't use the android:noHistory flag in your manifest for the Activity
documentation:
android:noHistory
Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen

It depends on how much memory your phone has, if your phone does not have very much memory, then it will destroy the activity to free up resources immediately. On new phones, this will not happen because they have plenty of spare memory.

You activity could be destroyed upon pressing the home button if the system is constrained and has determined it needs to free some resources. The documentation states that onDestroy() can be called if:
This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
Additionally, do note that the system can kill your program without calling onDestroy() after onStop() has been called. Therefore, any cleanup/data persistence code should be in either onPause() or onStop().

Well, it depends on a lot of factors. If you are facing this issue on Android 3.2+ devices, you should add screenSize property to android:configChanges
android:configChanges="keyboardHidden|orientation|screenSize"
Besides, also add android:launchMode="singleTop" to your launcher activity. Do note that you'd need to use Android SDK 15 or above as target, however, your app will work on older devices as well. Hope this helps.

another thing to check is whether your activity call finish() when onPause()

Of course may be memory problems, but before that check the manifest file, in the declaration of the activity, if you have "no history" declared (you don't want the activity to remain in the activity stack. Also you may using some flag when you create the activity with an intent.
Then, most probable answer is the one given by Alex Contour.

Related

Getting around onDestroy being called on orientation change?

I have a stock Nexus 5 running 4.4.2 (using ART if it matters) and I've found an interesting scenario. I have this as my onDestroy():
#Override
protected void onDestroy() {
super.onDestroy();
t.setText("onDestroy");
t.show();
}
It's a GPS oriented app so I'm up and walking around. I am using the technique mentioned in this question to show a lot of debug toast messages.
Anyway, when I rotate my app, the toast appears. I understand that the activity is destroyed and recreated for the new orientation, but how can I know what's really going on? How can I tell when my app is REALLY getting destroyed and not just being rotated? Similar to this question, I want to log out when a particular activity is destroyed.
Since Honeycomb, the isChangingConfigurations() method can be queried to check whether the Activity is being recreated due to configuration changes. Alternatively, the isFinishing() method can be queried on any API level to check whether the Activity is actually being finished, or is only being destroyed temporarily by the system.
As far as I can determine, the two methods should always return mutually consistent results in practice. The only point where they might have diverged is when the system kills the process to clear memory, but there are no callbacks or interaction with the app at that point.
The documentation of the onDestroy() method mentions the use of the isFinishing() method:
Perform any final cleanup before an activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
You can put it in a fragment with setRetainInstanceState(true) set. Place your code in the onDestroy() method of the fragment. Then, the fragment will not be destroyed on orientation changes.
First of all, you should not use onDestroy() to do anything because its not guaranteed to be called. I would put things on the onPause() method; I wouldn't even put things in onStop().
Also, Im not sure why you want to log out a user when they navigate away from the app. I would rather implement some kind of timer on the app or server to log out after x time.
Now, the answer lies in the documentation: http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
You might want to override onConfigurationChanged so that your activity is not restarted.
I found a couple of solutions which are really just patterns to detect when the screen rotates. Alternatively, you can determine that the device was actually destroyed by checking some static data member to see if it was initialized or not.
Configuration changed solutions:
The first one involves handling all of the configuration changes in the onConfigurationChanged callback.
"Note that this will only be called if you have selected
configurations you would like to handle with the configChanges
attribute in your manifest."
The second involves listening for Display.getRotation() which returns a Surface.ROTATION_* object. Which is the new orientation of your screen relative to the natural state of the device orientation.
Again, you can use the configuration changes along with the static member.
Add ConfigChanges.UiMode flag to the ConfigurationChanges attribute for your MainActivity class, and this solves the problem.
More details: Android Launcher "OnDestroy" gets called twice

android: when to use onStart(), onStop()?

I've read several posts that describe the difference between onStart() and onResume(): onStart() is called when the activity becomes visible, onResume() is called when the activity is ready for interaction from the user. fine.
I've always just added code to onPause() and onResume(), and never bothered with onStart() and onStop().
Can anyone give some concrete examples of what you might do in onStart(), vs. onResume()? Same goes for onStop() and onPause(), how is onStop() useful? I must be missing something fundamental here.
onStop() will (for example) be called when you leave the activity for some other activity (edit: almost. see commonswares comment about dialog themed activities).
For example if you use startActivity() in activity A to start activity B. When you press back in activity B you will return to activity A and onStart will be called.
This differs from some of the reasons onPause might be called without onStop being called. If for example the screen times out or you press the standy button onPause will be called, but probably not onStop (depending on memory available and whatnot), so it is a "lighter pause". onStop will be probably be called eventually even in this case, but not immediately.
Ok, but what's the use
Often there is no specific use, but there might be. Since your activities will keep its memory state on the stack even after you start some other activity, that stack will increase with the number of activities started (height of the stack).
This can lead to large memory usage in some applications. After a while the framework will kick in and kill some activities on the stack, but this is rather blunt and will probably mean a lot of states to be retained when returning.
So an example use for onStart/onStop is if you want to release some state when leaving an activity for another and recreate it when you get back.
I have used it to set listadapters to null, empty image caches and similar (in very specific applications). If you want to free the memory used by visible views in a listadapter you can recreate it in onstart and let the views be picked up by the gc. This will increase the likelyhood that the rest of the memory state of the activity will live on.
Some resources can be deemed good enough to save while the activity instance is alive and some only when it is on the front of the stack. It is up to you to decide what is best in your application and the granularity of create/start/resume gives you that.
onStart() works after onCreate() ended its task.
It's a good place to put a broadcastReceiver or initialize some state about the UI that should display consistently anytime the user comes back to this activity.
onResume() works when you come back to your Intent or Activity by pressing the back button. So onPause will be called every time a different activity comes to the foreground.
i think that your question is pretty explained here on the doc : read about the Activity Life Cycle

variables retaining values after app close

My app is retaining all of the variable values when it closes and this is effecting how it runs when reopened. Is there any way to reset them all upon app close? or is there a way to clean the app from memory when it is closed so to speak? For the moment I have just been setting all of the important variables "=0" in the last few lines of execution but I know there must be a correct way to doing this.
EDIT:
OK I thought that it would just be easier to reply here instead of individually to everyone.
The app is indeed staying alive in the background, I checked with advanced task killer. How would I get the ap to "Die" by presing the back button? I think this would be the easiest solution given how the app works:
open app > press start button > press stop button > results screen > press back button to exit.
so basically each time the app runs should be an independant execution.
Override the onPause, onResume, and onDestroy methods. onPause should save anything upon pausing, onResume should reload these values when it is resumed, and onDestroy will be called when your app closes. You can clean up stuff in onDestroy. See this link.
You app is probably not closing but remaining in background. Check advanced task manager and see if the app is running or not.
You need to familiarize yourself with the Activity Lifecycle.
You could leverage onResume() to reset your variables; also note onDestory() and onPause().
UPDATE:
Killing the application in its entirety each time the app moves to the background is an anti-pattern. You should really look at your application and follow the aforementioned activity lifecycle pattern and take the needed steps to insure your variables exist as you desire based on state.
I like what #Alex and #Jack said. To add to that, also consider that you can call finish() in your Activity if you want to force it to close up and return to the last Activity. Going along with this, also consider the use of setResult(int) (JavaDoc Here)
You can also set a flag on the Intent when you call the Activity you are questioning about. A flag like FLAG_ACTIVITY_NO_HISTORY could be helpful:
If set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished. This may also be set with the noHistory attribute.
List of Intent Flags
Uninitialized variables are bad. Don't do it. ALWAYS manually reset variables before using them for the first time.
the onResume() method will let you reset the variables when the program resumes, but will also do it when you return to the activity unless you add the logic that says you are coming from in the app, not the home page. Maybe onRestart() is what you really need? I'm not positive, but it's possible with onResume.

android: unusual way to start activity

In one activity I need to start another one but with one condition: if it was started before then it must be finished and started again. This activity show some information about system state (Theme.Dialog style) it also can start some services and so on. As far as I know when I do startActivity(intent) then onResume() will be called (if activity was started before). Does anybody know how to do it?
That's precisely how it should work. If you need to adjust the values on-screen, put that code in onResume(). What may not be obvious from its name is that onResume() is called when the Activity is first created as well. It's always the last method called before an Activity becomes active.
use the NEW_TASK_LAUNCH flag in the startActivity() call. Read documentation http://developer.android.com/guide/appendix/faq/framework.html#4
In the manifest file, in the activity attributes, you have the attribute launch mode, which let you specify how the activity must be launched (http://developer.android.com/guide/topics/manifest/activity-element.html#lmode).
Take a look at the description to see which mode suits most your needs. Then when the activity is brought to front, you can restart your service by overriding the Activity.onResume() method.
In one activity I need to start another one but with one condition: if it was started before then it must be finished and started again
There is nothing that only does this. The closest is to have the combination of FLAG_ACTIVITY_CLEAR_TASK|FLAG_ACTIVITY_NEW_TASK, but that has other side effects, such as wiping out any other activities.
As far as I know when I do startActivity(intent) then onResume() will be called (if activity was started before).
Not by default. By default, a second instance of the activity is created.

Android startactivity and stacks keep in memory

we start activity and do not calling finish() on existing activity it keeps existing activity in stack and move to new activity if we press back button we return to previous activity.
Its mean all previous activities not beeing called finish() keep remain into the memory(Stack)
Now problem is i do not want to call finish for every activity is there any centralize place where i can define that keep only last 3 activities in stack and remove rest of them ?
In the Android Manifest in the [activity] tag you can specify android:noHistory - Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen —"true" if it should be finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it. This attribute was introduced in API Level 3.
When launching new Intents that resolve to Activities, consider setting appropriate Intent Flags, list of such flags can be found here. Using these flags, you can re-order activities on the history stack and clear it too. There is an excellent description of this in the Activity and Task guideline documentation see here.
Alternatively, in your deployment descriptor also known as Android Manifest, set appropriate attributes for your activity(noHistory would be a fit for your problem).
Refer this for details.
It sounds like you're worried about memory usage and you shouldn't be: Android handles all this for you.
When one of your Activities covered by another of your Activities so it is no longed visibile to the user it is stopped. A stopped Activity should still retain all its state but can be killed by the system when memory is needed. This is why you need to implement the onStop() and onRestart() methods so that your Activity can recover its state after being killed and restarted automatically by the system.
For more detail you can read about Component Lifecycles in the Androind Fundamentals document in the Android Developer documentation.

Categories

Resources