Ok . . . I have read hours upon hours of advice and forums and developer pages to no conclusive answer.
what I have: is an app with 8 activities and each has a slightly different set of buttons to navigate to some of the other activities. Each activity has multiple forms of data collection, ultimately ending in an e-mail intent which collects all application UI data.
Problem: I cant seem to find the proper way to use the navigation buttons in conjuction with onSavedInstanceState so that no matter what, everytime an activity is started it will appear with any and all data the user has inputed(sp?) thus far, during this instance of the application. I dont want to save data beyond closing the app. I do want the user to be able to navigate back and forth as much as necessary within the activities without losing data until the app closes.
This is what I have:
Activity A: has buttons to: Activity B, C, D, E, and F(F=email intent)
Activity B: has buttons to: Activity G, and A
Activity G: has buttons to: Activity B, and A
Activity C: has buttons to: Activity H, I, and A
Activity H: has buttons to: Activity C, I, and A
Activity I: has buttons to: Activity H, I, and A
Activity D: has button to: Activity A
Activity E: has button to: Activity A
Is there a better way to set up my navigation? (this is optimal for the context I am fairly sure)
And what is the proper launch mode/Flags/savedinstancestate and whatever to achieve proper result? I can explain elaborate as much as needed.
I am aware I need to save the data the problem is setting up the activities so that the navigation buttons i have put in each activity always open activity showing all previously saved data (in the current task instance)
I have all activites set to launchMode:singleTask, I have not manually coded any flagsand I have set up onsavedinstance properly but something as simple as: Activity B-> Activity A-> Activity B (using only my buttons) Activity B saves nothing after going to A and back again (again I am not using back key, I am using my navigation buttons in the layout) How can I fix this??
Oddly tho Activity A DOES retain memory but none of the other activities do
Why you're using singleTask?
Aren't you looking for
intent.setFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
?
Related
I have two activities A and B. The A has a ListFragment which uses LoaderManager, whereas B activity shows a details about the item selected in the A's ListFragment. I've just noticed that when I use a back button to get from the B back to the A, the position in the ListFragment preserve, but when I use the up button (left-point caret) in the action bar, the A activity is recreated and thus position in list view is lost.
I would like fix this issue, but I am not sure about the best way how to do it right.
I come up with this solutions:
a) Use onBackPressed()
Replace the default implementation for the android.R.id.home (the up action bar button) in the B activity, and instead of the NavUtils.navigateUpFromSameTask(this) function call the onBackPressed() activity method. I've tested it and it works.
b) Keep use NavUtils.navigateUpFromSameTask(this)
But implement the onSaveInstanceState and restore listView position during onCreate method of the ListFragment used by the A activity. (I've not tested this approach yet)
Which of this solutions is better? Or is there any other (much more better) solution?
Solution a) is pretty simple and straight forward, but b) is probably better because the default implementation of the up caret is used.
Any ideas are welcome. Thanks.
Solution c is the correct option. First, though, an explanation of the problem with solution a.
There is absolutely no point in having two back buttons in your Activity. Furthermore, option a actually breaks the up button. The point of the up button is to provide a way for users to stay within your app when they have landed in your app from an outside source. For example, if you land on activity B from an outside activity C and if you are using your option a, then pressing "up" in activity B will result in activity C being shown. The behavior you would want would be for activity A to be shown.
As you can see, solution b is on the right track. You definitely want to go up to A and not back to C. However, simply storing the state in onSaveInstanceState will not cause the state to be retained. This is because onSaveInstanceState only gets called if your application may be killed by the system. It is not guaranteed to be called if your application was destroyed manually, and it certainly won't be called when a new instance of your Activity is created. If the Intent starts a new activity, then it will not have its state restored from the other activity.
There solution, then, is that you must write anything persistent to a shared preference file (or a custom persistent alternative). When doing this you can guarantee that all instances of an Activity share the same state across multiple tasks so long as their onResume (or wherever you restore state) is called. OR:
If you know exactly how you want your navigation to work, you can avoid writing everything to persistent state by using a combination of Intent flags and Activity task affinities. If you want to use the same activity as up even if you navigate into the application from an outside source, then you can leave your Activity A's affinity as default (linked to the application) and use something like Intent.FLAG_ACTIVITY_CLEAR_TOP.
Personally, I'd try the Intent flag approach first and failing that fall back to writing the state persistently. You just don't really want scroll location sitting on persistent storage if you can avoid it..
check out this presentation: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android. It answers to all of your problems.
I have an application that is based on windows principles , and doesn't not follows the android way . . .
Do not ask why , it is just an requirement, I know that should not be done that way....
Here is the problem:
I have an application that fires two transparent activities , activity A and activity B.
if activity A is shown than if the activity B should be shown the is no problem, because the activity B will be over the activity A.
But if the transparent activity B is shown then if I fire an intent the activity A will be over the activity B ,.. :(, the business logic is that if B is shown then A should be also shown but behind the A. Then is the user dismiss the B , only then the A will be visible...
I hope I describe this good, I far as I know this is not possible, but I want to ask more experienced people
if there is possibility to start some activity that will not be covered by others activities
NOTE: I am talking for preventing activities only from my application
Make A search for a special command keyword in its Intent extras, If it is found, A also launches B from its onCreate(). So, to launch A, use simple intent of A; to launch B, put the special keyword in A's intent, A will launch and also launch B.
I have activities in sequence as Activity A calling Activity B,When I am on Activity B I press Home button and start another Application (for example Map). If i stay on this second application for a long time say 5-10 minutes and then press Home Button again and choose to Start my application again, then Activity B is started again and works fine. But when i Press Back key - I return to my Activity A again (which is also correct) but it shows a Blank Screen. Ideally in correct version it should show me Acitivty A with the XML data is ListView form.
Alternatively, in the above description, when the other Map Application is started and if the user stay on it only for 1-2 minutes then the above problem doesnt not occur.
Can anyone suggest a solution on the same.
Is it that i need to check in Activity B whether Activity A is still there in Activity Stack (How do i do the same) and If its not in my Activity stack then re-create it.
I tried doing alwaysRetainTaskstate in my Android manifest file for Activity A. But it doesnt work at all
You don't have to do any of that, Android takes care of the technicalities for you - it will recreate your Activity A.
You just need to remember to save A's state when B is opened (take a look at Activity.onSaveInstanceState). When A is restarted, your saved state will be passed to onCreate.
You should really read about Activity Lifecycle
This should help.
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
I'm making an app which has a flow roughly as below:
User starts on the main screen with an empty list, hits menu, and goes to "add item." (Activity A)
User is given a new activity which allows them to specify search criteria, then hits "go" to do a search. (Activity B)
User gets a list of results, and can click on one of them to view more details. (Activity C)
User sees details of item, and can use a menu item to save it to their list in Activity A. (Activity D)
Right now, I am having each Activity call each other Activity for results, and then it is passing the result all the way back up the stack as it returns to Activity A.
Is there a way to jump this, since all I want is for a result in Activity D to get to Activity A directly?
Note that a user should still be able to navigate backwards (using the back button) through each activity, but if they explicitly save the item in Activity D, I want it to jump straight to Activity A.
I recommend just invoking the activities (not using the *ForResult) calls, then having activity D invoke Activity A with an INTENT_ADD_ITEM with data, then have Activity A add the item.
Hope this helps...
Just so that people can benefit from what I learned later...
The key to solving this problem is using flags with Intent, in this case using FLAG_ACTIVITY_CLEAR_TOP. Other flags are useful as well in controlling the flow of your UI.
It is a bad idea to try to solve this problem by chaining startActivityForResult() through activities. It means that it's difficult to change the flow of your application.