Does pressing Back always cause Activity to finish()? - android

I've heard that pressing the back button will essentially cause the current Activity to finish(). Is this always the case? Seems like it would be with the way it pops the Activity off the stack.
The one situation I'm not so sure about is when the root Activity in a Task has back pressed. I'm currently experiencing a very weird effect, described as follows:
On loading my application, the first Activity is for initialization, and once it finishes, it calls my main Activity (a TabActivity). This first init activity has android:noHistory="true" set in the Manifest so pressing Back from my main Activity won't go back to that. It goes to the Launcher. When I click on my App in the Launcher a second time, the initialization activity loads again, and loads the main Activity when done. Almost immediately after, it loads a second instance of my main Activity. But ONLY after the Application has already been run once, and was exited by pressing BACK from the main Activity. It does it every subsequent time until I force quit the app or load a new version from the IDE.
Based on this, I am suspecting some kind of Activity instance is lying around and being reused, since it only happens on the second+ time I run the application (and exit with BACK -- using HOME just returns to the last state of the app, no big deal). Anyone have any thoughts??

I've heard that pressing the back button will essentially cause the current Activity to finish(). Is this always the case?
No it is not. The most activities have this behaviour but not all. For example you could create a Dialog and set it setCancelable(false) and it won't close if you click BACK button.
Furthermore you could customize activity behaviour on BACK button pressed by overriding onBackPressed
Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.
About your application behaviour..Did you verify if the activity launcher is finished after it loads your main activity? I mean if the onDestroy() method is called. Maybe after it runs the main activity it remains there and when you click back you just go back to the old Launcher...
hope this helps..

Read through the Activity and Task design guidelines on the Android developer site; they explain how the Home and Back buttons work. Obviously, if you override the default behavior (as mentioned by hara above), the back button will not finish the activity.
On your specific issue, check your logcat. You should be able to see there whether it is bringing an old process back to life or starting up a new one. If that is unclear, insert a couple of log statements into onCreate, onPause, onDestroyed, etc., so that you can see exactly what is happening with your process.

You can control BACK-BUTTON by writing the following code.
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK ) {
//preventing default implementation previous to
//android.os.Build.VERSION_CODES.ECLAIR
return false;
}
return super.onKeyDown(keyCode, event);
}

Are you running your activities with any special flags, such as singleInstance or singleTop? Those could be causing the oddities you're seeing. The easiest way to track down what's causing your problem is to absolutely fill it with debugging messages. For example:
In your initialisation activity, add a log in the beginning of onCreate to get the name of the activity such as this.toString(). More on why you want this line later.
When it launches the main tabbed activity, get the name of the launching activity and a message saying it's launched the tabbed one.
Override the onPause(), onStop() and onDestroy() callbacks and add debugging lines with this.toString() and also a message telling you which callback it is.
What this will do is tell you whether you've got multiple instances of the initialisation activity lying around. To this by comparing the name of the activities calling your main activity with the ones that were just created and the ones that went through to onDestroy.
If you don't know how to debug, use Log.d(LOG_TAG, "Your message here");. And then define a constant LOG_TAG String somewhere. After that, show the LogCat perspective in Eclispe by going to Window, show perspective (or view, don't remember exactly), other, Android, LogCat. The purpose of having a LOG_TAG constant is that you can set up LogCat to filter to that String and only show you those messages. It will make it easier to see them among the mass of system log messages.

The short answer to the original question is 'no'. This is largely because, unfortunately, not every developer follows the guidelines referenced by previous answers.
Yet the guidleines themselves mention exceptions, when the Back key should not call finish(). the most prominent exception is the Web browser, which has its own "back stack" for each window, so it must have its own custom handling of the Back key.

If there are no fragments on the back stack and a developer has not overridden onBackPressed, the activity will finish when the back button is pressed.
Here is the source code for Android 4.4.2 Activity.onBackPressed():
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}

just override onbackpressed().. on back press this method will get execute remove super and do what u want to do.

Related

How to show disclaimer once per run of app

This is harder than it sounds, which is why I'm asking for solutions.
Basically I only want the disclaimer Toast shown once per run of the app.
The app is in two parts, all are Activities.
It's shown when it starts in the first part, but you can hit a menu button
taking you to the second part of the app, which has another menu button
to take you back to the first.
The problem is that whatever initial settings you try to make in the first
part, when it starts up, are run again when returning from the second
part of the app, so it'll show again.
My last idea was that in the first part's onDestroy(), when the app exits, but is not the case in this situation, you set a boolean in settings,
to reset that the disclaimer can be shown, but apparently, onDestroy() is called on the first part before it goes to the second part.
Or, if you can get it to not show the first run, but behave properly
every time after that, that would be okay.
And there doesn't seem to be any method to be called when the app truly
is "killed", if there was that would be the way to do it, you could reset it there. Or if there was a method that was only called when the app first started..
Thanks!
You just need a boolean flag. Say we call it disclaimerShown. In onCreate() of Activity A, we check both the Intent Bundle and the savedInstanceState Bundle for this flag.
You can add the boolean to a Bundle when launching the Intent to start Activity A from Activity B.
If the user is in Activity B and presses the Back button to return to Activity A, you can override onBackPressed() in Activity B and include your flag there as well (though you'll have to catch this flag on onActivityResult() in Activity A).
If system initiated process death occurs in Activity A, the system will call onSaveInstanceState(Bundle bundle). So you add your flag to this bundle as well.
And if system initiated process death occurs in Activity B, you have nothing to worry.
And that handles all possible cases.
An elegant solution for this problem would be the ProcessLifecycleOwner.
This class provides callbacks to the lifecycle of your whole app (not individual activities) and you could use the Lifecycle.Event.ON_CREATE callback to show your toast once. Look at this stackoverflow question for a usage example of the ProcessLifecycleOwner.
It turns out that I already had an Activity that started before
my "Activity A", and I moved my disclaimer Toast there
and it works fine. You can't beat that simplicity lol.
Thanks for your answers!

What exactly does moveTaskToBack() do?

From the documentation:
public boolean moveTaskToBack (boolean nonRoot)
Move the task containing this activity to the back of the activity stack. The activity's order within the task is unchanged.
What exactly does "Move the task containing this activity to the back of the activity stack" mean? I know that each task is a stack of activities, but according the the above sentence, it seems there is also a global stack of tasks as well?
When I try this method out, the current activity moves to the background, and the behaviour seems very much like when clicking the Home button (e.g. the activity is not destroyed and can be resumed later). Is there any difference between calling this function and pressing the Home button?
There is not a "global stack of tasks." There's a global stack of activities, which can be from one app or from multiple. Let's say you have an app where you can click a link, bringing you to your browser. If the browser then calls a moveTaskToBack() method, then the original app activity will open, with the previous activities on the backstack still in place.
Now imagine instead of calling the moveTaskToBack() method, the user presses the Home button. Now, pressing Back on your phone will not take you back to the original app. You'll just stay on the home screen.

Calling finish() in onPause in child activity so that user refocuses into parent activity. Child activity gets recreated instead

I create a child activity "B" from activity "A". if the user should leave the app for any reason (most likely hitting the home button), I would like activity "B" to end and the app to be at activity "A" once the user resumes.
If I call finish() manually, activity B ends and it returns to activity A. This is the behaviour I would like to happen when the user leaves the app.
I have tried to call finish() in the onPause(), onStop() and in the onUserLeavingHint() of activity B. In each case, this appears to work correctly, and I can see mParent.finishFromChild(this); being called inside activity B.
However, as soon as the user switches back to the app, the onCreate() of activity B gets called and the user ends up in activity B.
How can I ensure I end up in the parent activity when I call finish() from within an onStop() (or similar) handler?
UPDATE: It appears that the issue is related to activity B being declared as using a SingleInstance launch mode. Removing this feature seems to have resolved the issue. Changing this has introduced other issues that I have since managed to fix.
The reason for this happening is that Activity B is set as a SingleInstance Launch Mode. The reason it was set to this (by another developer) is somewhat related to the reason I had wished the activity was ended when the app is in the background - it was to ensure the user could not reach this activity by hitting back on any other activities subsequently dispatched from Activity B.
To resolve this. I first ensured no activities could be created from B. To instead return from B and pass any required Intents on to A. Simplifying the back stack. (Calling activity B with startActivityForResult() is one possible way of doing this.)
Now, the reason SingleInstance causes this issue to arise in this scenario, is because Activity B is launched in a seperate new task. When the user attempts to resume, they re-enter this single-activity task. The rest of the app is running in a seperate task. The only thing the task can reasonably be expected to do is relaunch the activity. When the user presses back, the only thing it can do from there is to close the task (and hence appear to exit the app). For the expected behaviour to occur the user would have had to have selected the other, first task (through a long click of the task list).
Hopefully this self-answer can help someone who has encountered a similar issue.

Overriding onBack Pressed?

Correct me if i am wrong
"moveTaskToBack(false/true);" has nothing to do with the visibility of the Activity ,but has everything to do with Activity Stack,because many times on stackoverflow i find people being confused on this.
Now My Scenario:
there are two activites A and B
A is the root Activity
B is launched from activity A
the thing is i don't want my activity B to be killed after the back button is pressed,(just i want it to be invisible,and activity A to be visible which will happen on its own )so that i can restore its state afterwards.
so after searching a bit i came to know about
moveTaskToBack(false);,
which seemed to be the solution as it does not kill the activity (because the activity is not sent to back in the activity stack),but the only problem is.it works with Root Activity,and hence it will not work in my case.So is there any alternative which i can use with"non-root" activities,so that the state of Activity is restored....
I guess you have misunderstood
public boolean moveTaskToBack (boolean nonRoot)
Added in API level 1
Move the task containing this activity to the back of the activity stack. The activity's order within the task is unchanged.
Parameters
nonRoot If false then this only works if the activity is the root of a task; if true it will work for any activity in a task.
Returns
If the task was moved (or it was already at the back) true is returned, else false.
Back Button by default takes you back to the previous activity. It pop's the activity from the back stack and the previous activity in the stack takes focus.
Save the state of the activity in onPause restore it in onCreate or onResume. To store values persistently chekc the below link for storage options.
http://developer.android.com/guide/topics/data/data-storage.html
http://developer.android.com/guide/components/tasks-and-back-stack.html
You may want to check the answer by commonsware in the below link.
https://groups.google.com/forum/#!topic/android-developers/4Pz6LrzVpx0

Android back button behaviour

Let's say we have a default, empty activity with default behaviour, launched with default intent flags. User presses back button on the device. The activity disappear... but how, actually?
Is pressing back button behaving the same way like finish()?
Is the activity immedietely destroyed (onDestroy is called)?
Is the activity guaranteed to be destroyed, but not immedietely?
Is there any chance the activity won't be destroyed and this instance will be reused when this activity is launched in the future? (so only onPause and onStop -> onStart and onResume are called?)
I'm looking for a reliable answer, so please do not answer if you are not absolutely sure what happens here.
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
This is a subchapter from the official Android documentation that addresses your question. It is a subchapter of the topic Managing the Activity Lifecycle, which can be read here:
http://developer.android.com/training/basics/activity-lifecycle/index.html
It is definitely worth reading the whole chapter to get to know the details about Androids Activity behaviour. But the subchapter ( first link ) is the relevant part to this question.
you use should look into this try this
and please tell specific what you wish to do with back button for your default activities ......
When you press back, (if not intercepted by anything like the keyboard, fragment, activity, etc) the OS (via ActivityManager probably) will try to show the user the previous activity in your current task (again, ignoring fragments' back stack).
If there is no such activity, the task will be terminated and you'll go to the previous task - the home screen most of the times or some other application that might have launched your app.
You'll get onDestroy called soon (it depends on how long it takes to start the next activity but on a good phone it should be under 100-200ms).
Your activity instance won't be reused after onFinish. This happens before the activity is destroyed so if you need another activity of the same type, the OS will create another instance.
When the user presses the BACK key, the current activity is popped from the top of the stack (the activity is guaranteed to be destroyed, but not immediately, may be when the system resources are low) and the previous activity resumes (the previous state of its UI is restored).
Which actions does the back button/back key on Android trigger?
Definitly onDestroy() is called .....There are a few scenarios in which your activity is destroyed due to normal app behavior, such as when the user presses the Back button or your activity signals its own destruction by calling finish().

Categories

Resources