lets imagine this application like enclosed image. R stands for Root activity and A and B are other activities. A is for displaying of some list, B stands for displaying detail of some value. From R I can get by 4 buttons to 4 A activities. My question is, whether in this scenario is A activity initialized for each time or I would be using only one A activity among whole application. If user selects A in right top corner activity A, then displays detail B and then from detail B goes to another list (but based on A activity). Will he still got the same content from the first A or he can have "new" A activity with another list?
Here is the point - I will be having let's say hundred of activites. Lot of them are "forms" displaying some content, application will have about 50 variants of those forms. Can I make for each form one activity a reuse it again in my activity without having connections to past usage of this activity?
Use android:launchMode="singleInstance" in your manifest if you want a single instance of your activity class
By default activities start over entirely every time you open them with a call to startActivity(). If your activity starts a new activity, it will essentially be put on to an activity stack and is paused while the new activity starts. If the user presses the back button, the last activity on the stack will resume as it left off (though I don't think this is 100% guaranteed as Android will kill off tasks as it needs resources so I wouldn't assume it).
So if you have this chain here:
A->B->C->D
where each letter represents a new activity with absolutely no flags or changes.
If the user is at D and presses the back button, C will resume. D is popped from the stack. If the user decides to go to activity D again, a new D will start as if it didn't happen (assuming you didn't save any persistent variables). If the user presses back twice, the application will be at B where C and D are no gone.
You can manipulate this chain with various flags like singleInstance to keep its state, or noHistory to ensure it doesn't get put to the stack (meaning it will be skipped if the user presses back).
Very detailed description of the various attributes
Related
I know that in Android, if stuff is idle for a while, the operating system will devour things to free up memory.
So if I have a first Activity, and I invoke a second Activity by using an Intent, and then invoke a third Activity using yet another Intent, I can use the back button to go back to the previous Activities.
But let's say I stay on the third Activity, and let the phone idle for a while until the OS decides to devour my app for memory. If I open the app again, will I have lost the stack I have formed from my Intents? Will I still be in the third Activity with the ability to press Back and go to Activity 2, then Activity 1?
The OS will handle how long a particular Activity stays "active" in memory. However, the "stack" shouldn't change, regardless of whether an activity is "active" or not. This is where the Bundle comes in handy and the methods: "onSaveInstanceState()" and "onRestoreInstanceState()".
Implementing these methods properly is the difference of the activity reappearing on the screen in an empty state vs. with its previous state maintained.
Some documentation on Recreating an Activity
The backstack stays intact for the task in hand. It will always stay in task and whenever the user presses the back button, it will go through the back stack like popping the last item. However, not all the activities in the stack are in the foreground. Usually, only the last item put into the back stack (the top of the stack) is in the foreground and if there are multiple apps/tasks open this may not even be true. Here is a great diagram to show this.
Now, lets say a user opens a task with a couple of activities in its back stack. The top activity is in the foreground and is running normally, but to preserve memory the other activities were destroyed. So now when the user presses the back button, the task knows what activity was in the back stack and knows it is now destroyed. So, it will recreate it following the Activities lifecycle and any data that was in it will be lost. One way to preserve it (mentioned by original answer) is using the onSaveInstanceState() and onRestoreInstanceState(), which save things in a bundle that Android preserves for the user so data can be saved. All of this information can be found in the docs. To answer your question more clearly, yes you will be in the activity you think you would be in, but you can treat it as a new instance of that activity and to recover the data from before to display it in the same way, you should use bundle and implement the methods aforementioned.
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 have been studying the Android Activity Stack. The book mentions the following:
Android uses a last-in-first-out collection of all the currently running
activities.
However, when I look at the diagram:
It appears that the first activity to be put on the stack is the first activity to be removed off the Activity stack (hence a FIFO queue rather than a LIFO queue). Any help in understanding this would be appreciated.
A notion of LIFO (activity stack) refers only to vertical arrows on the diagram you posted, i.e.
last in - last activity X displayed on top of others
first out - the same last activity X to be removed/destroyed when user presses back button
Don't be confused with bottom arrow Removed to free resources - there is a completely separate mechanism for handling that by OS which involves onSaveInstanceState calls.
It mean that Suppose you start the Activity A then Activity B then press back from Activity B then again press back from Activity A.
It simply mean that Last activity pop first that is called LIFO.
What exactly is the attribute taskAffinity used for? I have gone through the documentation but I couldn't understand much.
Can anyone explain task affinity in laymans terms?
What is Android Task Affinity used for?
An android application has Activities that form a stack like a deck of cards. If you start an android application, and start five activities A,B,C,D,E. They will form a stack
E - chat view
D - weather screen
C - map view
B - weather screen
A - login screen
E was the last Activity to be started and it is showing. If you close E, D will be shown. If you close D, C will be shown. etc.
Notice that Activities B and D are the same activity. What if the user were to make some modifications to the D weather screen, and then decided to close the activity, then close the C Map view?
Then the user would be back at the weather screen and the user would be unhappy because the changes made at level D weather screen were not saved in level B weather screen. Although it's the same activity, it's a different STATE of that activity.
The user had a 5 layer stack of activities, and two of them were the same activity. Popping all 5 off the stack will create the phenomenon where you will be interacting with two different versions of the same activity and can be quite confusing.
Users don't usually think in terms of a rigid stack of activities. They think: "ooh the weather view I'll make a change there" and then they want to go back to the Map view. Then back up again because they want to go back to the Login screen. Why is the B weather app showing and why didn't it save the settings from level D?
The programmer might be able to alleviate some confusion if Activities B and D were linked in state. That way changes to one changes the other. Each time the user opens up a new weather screen, it secretly opens the single instance of the weather screen.
In these circumstances, changing the taskAffinity of the Activity might be desirable. The user would change level D. Then back up to level B. And see the changes in B that were made to D.
The program keeps a stack you can backup through, which is nice, and when the user opens up X instances of the same activity in random places, they are all one.
Slideshow with more explanation:
http://www.slideshare.net/RanNachmany/manipulating-android-tasks-and-back-stack
The affinity indicates which task an activity prefers to belong to.
The affinity comes into play in two circumstances:
When the intent that launches an activity contains the FLAG_ACTIVITY_NEW_TASK flag.
When an activity has its allowTaskReparenting attribute set to "true".
Please refer http://developer.android.com/guide/components/tasks-and-back-stack.html
You can find all cases (and some times edge cases) in this detailed presentation
Please, refer Manipulating Android tasks and back stack