My application start foreground service witch keep connection to server. It's show notification with pendingIntent witch show MainActivity. When i (user) tap on application icon (on desktop or application list) it's show "task stack". I mean if was lunched MainActivity it shows it, if user go to activity B or C (or lunch some other activities) it shows it (i mean top activity from task stack). There is a problem - if user tap on notification he see again MainActivity (on the top of the stack) but i expect top of tack stack (activity B,C or other witch was lunched by user at the end).
Half solves when i set attribute for MainActivity "singleTask", now it's always root of task stack, BUT a'm loosing all activities (B, C and other wich user lunched). Solution like in Reuse Activity on Top of Stack simular, but i need only one activity at root.
Maybe my logic is wrong and i need some another way to resolve this problem. But i want to know how can i programmaticly show task stack (top activity) like application icon does?
The documentation Tasks and Back Stack describes how to handle navigation correctly.
In short, if users tap on your navigation and you take them to an Activity in your app, when they click Back they should up in your app's Activity hierarchy until they reach the Home screen. They should never go to the stack in another task. That is, if they're in your app in Activity C, and you send a notification which they click that takes them to Activity A, then clicking Back should take them to the parent of A, and not to C. If they want to go to C, they can use Recents.
On older platforms, Recents isn't available.
This is by design.
To construct the proper synthetic back stack, use TaskStackBuilder
Related
I have three top level activities in my application. Activity A, B & C.
Each one of these activities hosts a navigation drawer. I am trying to figure out the best way to manage the activity stack between these three activities.
For example, When I start the application, Activity A is launched.
Activity A has a navigation drawer like Activities B & C. When I click on Activity B in the drawer, Activity B is launched and clicking on Activity C in the drawer launches Activity C etc...
I don't want to finish these Activies when the drawer launches a new Activity because they load data from a backend service, and when I click the back button I want it to send the application to the background.
Essentially, I am looking for a way to launch the activity if it does not exist, and if it does, just resume it. How can I accomplish this?
I think decoupling retrieving data from the activity is the best option.
The following paragraph is from Tasks and Back Stack:
Because the activities in the back stack are never rearranged, if your application allows users to start a particular activity from more than one activity, a new instance of that activity is created and pushed onto the stack (rather than bringing any previous instance of the activity to the top). As such, one activity in your application might be instantiated multiple times (even from different tasks), as shown in figure 3. As such, if the user navigates backward using the Back button, each instance of the activity is revealed in the order they were opened (each with their own UI state).
So in your case, grabbing the data in the background when the app starts using async tasks and storing them in the database might work out better.
One way to do it would be:
On create of the home activity, quickly grab the home activity's data via async task while showing a progress bar. When done, store it, and display it. Then, launch async tasks for the data for other activities. There are some conditions that could be tricky. For example, you have to make sure you show a progress bar if the user quickly switches to Activity B or C before your data is ready.
Perhaps using a singleton might suite your needs if you do not want to use the DB. Depending on the size of your data, parceling your data and passing it through a bundle might also prove to be a good technique.
I am new to Android Programming.
I want to understand how Activity Stack is maintained for a particular Android Application and how does it changes based on user navigation.
For example, if there are multiple activities then how Activity Stack behaves when user clicks on Back Button or Home Button or launches a new Activity?
I was trying to find a suitable post where I can get all the information, but I did not get any. Can somebody please suggest me some links/posts where I can learn this?
Thanks!
Edited:
Links/Posts that I came across so far:
onSaveInstanceState is not saving my values ( onCreate input Bundle is always null )
Saving Android Activity state using Save Instance State
Android: Launch mode 'single instance'
Do you mean activities and the back stack?
Here is a link:
http://developer.android.com/guide/components/tasks-and-back-stack.html
A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack), in the order in which each activity is opened.
The device Home screen is the starting place for most tasks. When the user touches an icon in the application launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no task exists for the application (the application has not been used recently), then a new task is created and the "main" activity for that application opens as the root activity in the stack.
When the current activity starts another, the new activity is pushed on the top of the stack and takes focus. The previous activity remains in the stack, but is stopped. When an activity stops, the system retains the current state of its user interface. When the user presses the Back button, the current activity is popped from the top of the stack (the activity is destroyed) and the previous activity resumes (the previous state of its UI is restored). Activities in the stack are never rearranged, only pushed and popped from the stack—pushed onto the stack when started by the current activity and popped off when the user leaves it using the Back button. As such, the back stack operates as a "last in, first out" object structure. Figure 1 visualizes this behavior with a timeline showing the progress between activities along with the current back stack at each point in time.
I need this behavior in my app, "user must have to login in each time he tries to launch it(touching the app icon directly, or by task manager or via recent apps)"
So the activities are in this order (think the App name is Foo app)
S - Splash Screen
L - Loading Screen
Lo - Login Screen
M - Main Menu (Has list of tasks)
T - Task Screen
"User starts the app and proceeds as in the following order :
S -> L -> Lo (logs in) -> M (selects one of the Tasks) -> Task Screen
so while he is in the Task Screen, he presses the Home button and the App goes to the background and he uses another app. and lunches the Foo app again. So in this if he pressed the Back button, it shows the previously being used Task Screen??? and if pressed Back button again, it goes to the Main screen again, and so forth...???
This should not happen, simply what I want is, when the App comes to foreground, user needs to login and never be able to go to back to any of the screens.
Note : all the screens have extended a BaseActivity class which has extended the Activity class. and in there I have used onResume(),onPause() method and another custom method to find out when the extended child class goes to pause,and resume when the app comes from the background!!! And in some Screen I have had to use Fragments too...!
Thanks in advance for your time and help!
Add tag android:clearTaskOnLaunch="true" to root (main) activity tag in manifest. Then user will always return to this activity.
To jump to Login from any other activity, use:
public static void logoff(Context c){
Intent logoff = new Intent(c,LoginActivity.class);
logoff.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(logoff);
}
I am not going to argue why your question describes a not so pleasant user-experience, but what would you say about below solution?
Replace Lo, M and T as fragments. So after L you would have an activity (PostL) where you show first Lo fragment, then on user action you would add on top of Lo an M fragment by get(Supported)FragmentManager.beginTransation().add(id, fragment).commit(), then moving on you would replace M by T: get(Supported)FragmentManager.beginTransation().replace(id, fragment).commit(). - or you can add T on top of M, it's your choice as it might suite better.
In this PostL activity, in onPause() method you would call only get(Supported)FragmentManager.popBackStack() if the fragment backstack is consisted of more than one fragment - the bottom fragment is Lo.
In this way would be covered in both cases when the user taps on Home screen and re-enters the app (no matter from where), or any other app goes in the foreground. Also, if you consider correctly the backstack size, if the user taps back then he will always open the last fragment (that could be M or Lo).
I hope it makes sense ...
Lets say I have a base activity with a menu, when I click on menu item A, it goes to activity A. I open the menu again, and go to B. From B I go back to A, and back and fourth like this for a while.
So the stack would be A, B, A, B, A, B, ....
And when I hit the back button, it goes backwards through the stack as expected.
However lets say I don't want this functionality, so I add to my manifest, android:noHistory="true". So when I hit the back button it exits the application instead of going though the stack.
Now the illusion makes it seem, lets say if I'm in activity A, I use the menu and go to activity B, the stack would just be B, because I can't go back to A.
But, when using noHistory="true", does the true stack of A, B, A, B, A, B exist? Rather, is every call to an activity by using the menu instantiating a new copy of that activity, but the user can't see it? Would this be causing resource issues?
Or when noHistory="false", does the back button just call something like startAcitvity(intent) again or is it going through each new copy that was instantiated?
I'm concerned with resource issues and not slowing down a users android device.
From the docs about noHistory:
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.
Regarding your question:
does the true stack of A, B, A, B, A, B exist?
The docs would indicate no.
I'm concerned with resource issues and not slowing down a users android device.
You really don't need to worry about this. The OS should handle the cleanup of activities when memory is getting low. Its more likely that poor use of bitmaps or logic in your activities will result in performance slowdowns.
android:noHistory=“true” works :-
Let suppose you have opened "your app".
You are on homepage Activity now,
After it you go to the another(second) activity.Here from second activity you press the home button of mobile device or open the some other application.
Now again if you open "your app" it will go to the homepage of app instead of going to the activity which one you left the app(i.e.second activity).
I had few fragments in my app and it seemed difficult to get out to the home screen by pressing back button without entering Launcher Activity of my app. I used android:noHistory="true" in the manifest of the launcher Activity of my app and the problem gets solved now.
I'm using a custom Launcher application with Widgets that are used to launch (and provide status updates) for an application.
The application consists of a few Activities - let's call them A, B and C for simplicity.
A is the launched Activity. The user proceeds from A to B and then to C (never in any other order).
At any time the user can press the 'Home' button on the remote control and return to the launcher application.
If the user then presses the 'Back' button on the remote control they always return to the Activity they were last using (A, B, or C).
However, if they click on the widget (rather than pressing back) the Activity that is brought to the front seems inconsistent!
So, here is an example of what happens
From (custom) launcher, use widget to launch application
Activity A appears
User presses a button that launches Activity B
Activity B appears
User presses 'Home'
Launcher appears
From (custom) launcher, use widget to launch application
Activity A appears NOT B
Sometimes I get Activity B instead of Activity A - but I'm not sure under what circumstances. I want to get the Activity at the top of the stack to be displayed and never any other Activity (Activity B in the example above).
I've read Google's documentation about the Activity flags ("single-task", "single-instance", etc...) but nothing seemed to jump out as the solution to my problem.
In my case, Activities A, B, C only make sense when run in that order - and it never makes sense to see a previous activity unless you explicitly go back to it.
I'm not sure if the problem is the way the widget is launching the application or whether there is something I need to specify in my manifest or something else.
Any ideas?
Thanks,
Dan
Isn't that what's supposed to happen? Isn't your widget launching activity A? Would you expect it to launch activity B if you are asking it to launch activity A?
(Althought you say that you get B launched sometimes. Isn't this related to the app being forced out of the memory?)
I'm sorry, but this is not an answer, but rather some additional information related to that same question.
I have found a pattern for Activities when relaunched after home button is pressed.
See my question for all my research:
Android Activity Stack is not working as stated in the docs - last activity in task stack not shown
Hope this can be of help...
I have been reading that the suggested fix for this strange behavior is the use of a "Dispatcher" class as Main that will launch the activity based on the application state...or you can also keep track of all the activities opened that need to be restored...but this can become really cumbersome when having a complex UI application design.