Android Back Stack - UP button method - android

I have Activity A (Main) and Activity B.
Fact: Activity A has: android:launchMode="singleInstance"
Usual scenario is:
User launches application > Activity A.
User clicks an item > Activity B
3.A. If user clicks on back/up buttons > Back to A (without calling finish() on B)
User clicks the SAME item as before > Forth to B.
At this point he can go back and forth without new instances. It's all in the stack and it doesn't recreate activities. (All right!)
3.B. If user clicks Home, then goes to task manager and brings the app to front > Activity B (all good, so far)
If user clicks UP button, it goes to TASK MANAGER, and I want it to go to Activity A (back button is expected to work this way, so let's focus on UP button).
Here's the implementation I have in Activity B for BACK and UP buttons.
#Override
public void onBackPressed() {
moveTaskToBack(true);
// I don't want to finish() the activity, so the user can reclick the same
// item without reloading the whole activity again (webview slow when parsing html).
return;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
moveTaskToBack(true);
// I don't want to finish() the activity... idem.
// I need to implement here the bring Activity A to front
break;
}
}
So, what I want is: to "Go Back" to Activity A keeping the same idea of using the stack to reload Activity B if needed, without using Intents (unless it calls activity to front, without adding items to the stack.)
Let me know if I explained myself clearly and if you need more info.
UPDATE:
I've found this at: http://developer.android.com/training/implementing-navigation/ancestral.html
This is how I adapted it.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, Activity_A.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
moveTaskToBack(true); // I want it this way. Don't worry.
}
break;
}
}
But the method NavUtils.shouldUpRecreateTask is ALWAYS returning false.
I did the http://developer.android.com/training/implementing-navigation/ancestral.html#SpecifyParent part, so that's not the issue.
My problem is that I want to recognize if Activity A exists in the stack, for when i.e. the app is launched from the task manager.
How can I achieve this?
Thanks.

moveTaskToBack moves the entire task to the background. it doesn't finish the activity.
in order to have full control of activities, you have some possible solutions:
create your own global manager for the activities, monitor each of them through all of their lifecycle and decide what to do on each event.
you could also finish each activity as soon as you go from it, and put "it" (just its name or something) in a stack and restore its state when you come back to it.
use fragments instead, and manage them all on a single activity. be warned of configurations changes though.

Related

Android Navigation and activities (determine which activity is parent)

I have three activities: A, B, C
From both Activities A,B I can call
startActivity(new Intent(this, C.class));
So the logic would be something like A->B->C or A->C .. now when I am in C, I would like to get back to B or A depending on from which activity was C started.
Now the question is, when I am in Activity C, how to get "Back" to the parent activity, from which I opened this activity C?
I have been trying something with NavUtils and Intent.FLAGS, but I was not successful.
BTW: I can not use finish() or onBackPressed(). I am using custom dynamic created theme in my app and when I use onBackPressed() it will show a default application theme (default white screen with icon) before the desired activity is loaded.
Thanks for any help.
in your manifest add this to activity C so this part solves the back button.
<activity
android:name="your.package.name.C"
android:launchMode="singleInstance" >
</activity>
lets solve up button:
you must use putExtra that indicates the parent of C activity. for example when you want to call it from activity B do this:
Intent i = new Intent(B.this,C.class);
i.putExtra(MY_PARENT,"B");
startActivity(i);
and in activity C store MY_PARENT value in a string called parent. then when the user press UP button read that and go to the parent.
that means in activity C :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
Intent i = new Intent(C.this,Class.forName(parent));
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
You may create and process too many objects in onCreate method of your Activity, so that causes the delay that you see before the desired activity get loaded...
You can do all those creation and processing in an AsyncTask and keep your onCreate method clean, then you won't see that delay anymore.

Android Application Lifecycle and back button

I've read the Android Docs on the lifecycle of an activity. However, I am curious as to how different activities within an application behaves.
From some tests that I've done, transitioning from Activity A to Activity B within the same application via an intent pauses Activity A via onPause() and creates Activity B via onCreate().
The strange part is when Activity B transitions back to Activity A.
If the hardware back key is pressed, onPause() is fired for Activity B and onResume() is fired for Activity A. This is what I would expect.
However, if the back button on the ActionBar is pressed, onDestroy() is fired for Activity A followed by onCreate() and onResume().
Why is this so?
The "back button" on the ActionBar is called the "Up Button". This is the expected behaviour of the Up Button, if you take a look of the implementation of the code which performs the "up", you see that Activity A is recreated.
Intent parentActivityIntent = new Intent(getApplicationContext(), MainActivity.class);
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();
You can define what the "Up" button should do, however, I suggest to stick to the default behaviour.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Your Code Here.
break;
}
}
Why?
The Up Button (in contrast to the back button) should navigate one level higher in the application hierarchy, always. The back button should go back, even if it will leave the current application.
You can't just call finish on the current Activity, because the parent Activity could already be garbage collected and don't exist anymore.
I heavily suggest to read the official Android Design Guidelines, especially the part about Up vs Back.

Navigating Up to an activity that expects extras

I have Activities A, B, and C in my app and they flow in that order. If I implement the Up button in C, I want it to go back to B. The code stub that Eclipse generated is this:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
However, B expects extras to be passed from A in its onCreate method. The relationship between B and C is that C allows the user to set some settings that affect how B is displayed. I'm currently handling saving the changes in C in onPause(). Should I just finish() C when user presses Up instead of calling navigateUpFromSameTask(this)?
If you're going to be returning from C back to B your activity will be created again, if you use standard launch mode. onSaveInstanceState will not (reliably) work.
Declare the launch mode of your activity B as:
android:launchMode="singleTop"
in your AndroidManifest.xml, if you want to return to your activity. See docu and an explanation here.
I believe you're having a similar problem to this? Essentially, if you're going to be returning from C back to B, there's a possibility it's going to need to call onCreate() again. This means that the extras you obtain from the intent are going to be gone, so you have to store them with something like onSaveInstanceState.

ActionBar Up button and Navigation pattern

I want to implement Navigation Pattern in my app with Up button in ActionBar.
I have Details Activity, here I can come from home, favorites and search screen. Also I can open this screen from browser(handling specific url). When user press Up button, I use flush() method, to emulate back navigation. But for case, when user come from browser, I want to open home screen instead of previous browser activity. How I can recognize, that previous activity was from another app, and navigate to home screen?
Up Should always navigate to the hierarchical parent of the activity and Back should always navigate temporally.
In other words you should leave Back as it is.
As for Up, it should always go to the same place no matter where it came from. So if you normally come to the DetailsActivity from YourListActivity, Up should always go there no matter where you came from. What is the most likely place is up to your discretion, but it should always be the same.
If you come to the Details Activity from a non-normal location (such as the browser, another activity, widget, or notification) you should recreate your task stack so navigation using up results in the same path. Here is an example from the Android Developer Training:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, YourListActivity.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is not part of the application's task, so
// create a new task
// with a synthesized back stack.
TaskStackBuilder
.from(this)
.addNextIntent(new Intent(this, HomeActivity.class))
.addNextIntent(upIntent).startActivities();
finish();
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
}
Here is the Android Training on Implementing Navigation
(http://developer.android.com/training/implementing-navigation/index.html).
You will need the support library for NavUtils and TaskStackBuilder.

Back functionality in android

I am developing an application which starts from LoginPage. When user Login then he moves to Main Screen where grid view for different departments are present.
Every page of application except login page has a Footer which have different Icons like Home, logout, etc.
I want to add conditional back functionality using mobile back button. Some conditions are as follow:
1) LoginPage ---> Main Screen ---> On back user should log out and go to Login Page
2) Main Screen --> any department ---> Any Sub deprtment --> If user press Back button then go to back in same order
3) User is any where in application ---> If press home button from Footer ---> Comes to Main Screen --> No back functioality to go on previous page, It should follow condition 1.
4) If User on Login Page then he will exit from application on pressing Back Button
5) If User on main Screen then user should logout and go to Login Page on preseeing Back Button
I have tried with "noHistory=true" in Manifest and with Intent flags in Activity file.
Can any body suggest me best way to solved out it.
shouldn't be a problem, all you have to do is override the onBack function and add the logout process.
not a problem, the normal behavior of back buttons is exactly that.
DO NOT DO THIS!!! BAD BEHAVIOR.
normal behavior of back button.
that was step one.
this is used for exit from application on back press.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
System.exit(0);
}
return super.onKeyDown(keyCode, event);
}
if u want only back then remove System.exit(0) from above code .
By using this you can manage your all condition which one you want.
Use a stack globally to save screens order. Stack must be available in application level. And get the screen order when you click on back button. Write switch case for screen order and start that activity. that's it.
for example.
crate a class class MyStack{
//here declare a static stack
//create setter,getter method for assinging values to stack
}
when starting new activity assing screen value in stack with setter method
if you are starting a activity from main screen assign 1 into stack, you are starting sub screen assign 2 into stack.
when click on back get that value
switch(value){
case 1: //start mainscreen break;
case 2: //start sub screen break;
}
With what I understand, you cannot override the functionality of home button. By default, it minimizes your app with its current state, by calling onPause(). When you open the app again, onResume() is called and starts the app from where it was paused. As far as your back button functionality is concerned, most of the above answers are fine.
Try,
#Override
public void onBackPressed()
{
finish(); //finishes the current activity and doesnt save in stock
Intent i = new Intent(CurrentActivity.this, Login.class);
i.addflags(Intent.flag_activity_no_history);
startActivity(i);
}
Try this to trap events on the back button
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK) {
Intent Act2Intent = new Intent(thisActivity, Activity2.class);
startActivity(Act2Intent);
finish();
return true;
}
return false;
}
on each activity implement
OnBackPress().
Override it and add the functionality you want like logging out, clearing history stack and start new(previous) activity.
I think simplest approach may be to override back button in your "Main Screen" activity so that when back button is pressed you can do :
1. Executing log out logic:
2. Explicitly call your Login Page
This may give the behavior you are looking for.
On how to override back button, you can refer to this link:
http://android-developers.blogspot.com/2009/12/back-and-other-hard-keys-three-stories.html
Hope this helps!

Categories

Resources