Managing an Activity with many states - android

I have an activity that has possibly many different states.
For example
no internet
no license
logged in
not logged in
pending
error
restricted
deprecated
At the moment I have if statements that determine the appropriate state of the application and enable or disable views as required. I was thinking that some sore of STATE pattern might be better.
Can someone give me some idea of how I might do this with an Activity like this? Or in this case is an if statement like this a better option as the views are tightly coupled to the Activity anyway.

I wouldn't disable the views for some of thise things ie no internet. Just let the user try to interact and give relevant error messages.
A good rule of thumb is that if you're changing the views significantly from one state to the other, maybe it should be a different activity? There should be very little reason to change the LAYOUT of views based on state.

This question is as old as the internet now, but the OP should really check out Stateless4J.
It provides lightweight Finite State Machines with easy syntax. I use it in all my Java projects.

Related

why using android:configChanges is a bad practice

I have gone through different posts and questions for handling rotation and AsyncTask. In each post it is mentioned that using android:configChanges
is a bad practice. But i didn't find the actual reason why it is discouraged and why it is a bad practice. What are the disadvantage if we use android:configChanges to handle orientation.
Note:
I know it is already answered how to handle orientation and AsyncTask. but I want to know reason behind not using android:configChanges.
Well, you need to remember that an Activity can be restarted for multiple reasons.
For example, one of these reasons is when your app is in the background and the OS decides to kill it (with your Activity, of course) to reclaim memory.
When you return to your app, the OS will try to recreate your Activity as you left it, but will fail to do so, because you decided not to bother with it, just used android:configChanges in your Manifest.
If you make sure your app can recover properly from a restart, android:configChanges might not be necessary at all. Because of this, the need to use android:configChanges might indicate some flaw in your app, that may worth to take a look at.
It's not bad practice to use android:configChanges, but it pretty easily can be, if you don't understand exactly what you're doing.
To sum up all what i got form #user13 answer and other stackoverflow questions and blog posts i would like to share my finding to clear some very important aspects.
(user13) It's not bad practice to use android:configChanges, but it pretty easily can be, if you don't understand exactly what you're doing
Using this technique prevents you from easily using configuration specific resources. For instance, if you want your layout or drawables or strings or whatever to be different in portrait and landscapes, you have to manage it yourself if you use android:configChanges.
You need to override and use onConfigurationChanged() method to perform specific action if you decide to use android:configChanges
As user13 mentioned Activity is recreated not just due to orientation change but there are multiple reasons due to which activity can be restarted. Therefor activity restart should be handled for all causes. using android:configChanges only handles one case and there will be unhandled cases of activity restart which will cause a potential bug.
There are multiple and better ways to handle activity restart and plenty of help is also available on stactoverflow so android:configChanges should be used as a last resort according to documentation.
Using android:configChanges is good practice if you know what you are doing.
Just always test how your application how it behaves when it is restarted by system to stay comfortable for user so some state has to be saved all the time but not all.
With config changes like this:
android:configChanges="locale|keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
Your application will restart rather rarely on new devices that have a lot of memory. If it restarts it's not so unexpected for user anyway, as user had attention elsewhere and came back to app. User don't have to be in exact same state after restart if it happens by manual killing of application or application restart because of some other heavy tasks (playing game) user is doing, the user experience is important here.
If you need to refresh List just for different layouts for orientations changes or you need to hide some view elements you can call:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
_list.reloadData();
_editorButton.visible(isPortrait());
}
(I use my custom classes but you get the point)

Android vs configuration changed

I apologize for my English but translated with google. I'd like to understand why Google with Android restarts the activity at each change and you lose all the data displayed. How do you solve this problem? Could not they make it optional this thing?
On every forum I read to use the methods onSaveInstanceState, onRestoreInstanceState, onConfigurationChanged, but how to use them is not explained well. If I have a complex application, with many objects, with EditText, with Markers, Polygons, I'm forced to save everything by hand with temporary variables? There is another way faster and easier to do it? Do you have any practical example to show me? I hope you know help me understand, thank you all.
It is an optional thing. In your manifest, add android:configChanges="orientation|screenSize" to your activity and it will turn off that behavior.
Really there's only 1 good circumstance to not override it- if you have no AsyncTasks, no Threads, no Loaders, no bound services, AND you have separate layout.xml files for landscape and portrait. That's about the only time it doesn't cause more pain to recreate than it saves. It's google's biggest screwup in the API.

Why using Fragments?

I have read the documentation and some other questions' threads about this topic and I don't really feel convinced; I don't see clearly the limits of use of this technique.
Fragments are now seen as a Best Practice; every Activity should be basically a support for one or more Fragments and not call a layout directly.
Fragments are created in order to:
allow the Activity to use many fragments, to change between them, to reuse these units... ==> the Fragment is totally dependent to the Context of an activity , so if I need something generic that I can reuse and handle in many Activities, I can create my own custom layouts or Views ... I will not care about this additional Complexity Developing Layer that fragments would add.
a better handling to different resolution ==> OK for tablets/phones in case of long process that we can show two (or more) fragments in the same Activity in Tablets, and one by one in phones. But why would I use fragments always ?
handling callbacks to navigate between Fragments (i.e: if the user is Logged-in I show a fragment else I show another fragment). ===> Just try to see how many bugs facebook SDK Log-in have because of this, to understand that it is really (?) ...
considering that an Android Application is based on Activities... Adding another life cycles in the Activity would be better to design an Application... I mean the modules, the scenarios, the data management and the connectivity would be better designed, in that way. ===> This is an answer of someone who's used to see the Android SDK and Android Framework with a Fragments vision. I don't think it's wrong, but I am not sure it will give good results... And it is really abstract...
====> Why would I complicate my life, coding more, in using them always? else, why is it a best practice if it's just a tool for some cases? what are these cases?
I am sorry if I wrote too much, and thanks for your time. I hope I will get your attention, because I really need ideas and experiences about this topic.
Best regards, Ahmed
You shouldn't always use fragments. Fragments have their uses, such as when you want to page in and out parts of the screen or when you want to drastically change the UI in different orientations. When they make sense, use them. When they don't, skip them. I find they make sense in maybe about 10-20% of apps- I rarely see the need.
If there's a certain positive aspect apart from the simpler reuse of logic through different layouts, it's the ability of Fragments to be kept alive by the system at orientation change, aka while an Activity is reconstructed from zero, a Fragment can retain its instance, and therefore using them is more stable than an Activity. Also, switching between Fragments is quicker.
Personally, if I don't need to mess around with different orientations and layout sizes, I still prefer using Fragments and a singular container Activity around it, for stability and seamless switching between the different screens.
Its quite a general question and not directly related to a specific programming problem. But in my opinion good software is based on good design and therefore a good understanding and best practices. So your question is a good one for stackoverflow.
So, what about fragments. It took me a while to understand why you could or even should use them. As #pskink said, you can easily live without them. But if you are planning to rollout your software on different devices, you should definately think about fragments.
The screen resolution and density is not the only problem. Think about a smartphone. The screen is much smaller, so you can not present your app the same way as you can on a tablet. For instance a master detail flow. Left side, a list of elements and when you click one element, you will see details of that element on the right side. Easy to do on a tablet. But on a smartphone you would put the master-view into one fragment and the detail-view into another one.
You got two options to realize that scenario. Either programm different activities for smartphone and tablet but because they are actually doing the same logic, it's better practice to put the logic into fragments and reuse those fragments in two layouts (phone/tablet).

State Machines and Android. Is there a way to only show the methods that are available at a certain State?

Greetings good people of Stack Overflow.
I am in need of the help of anyone who knows a bit about State Machines and/or Android Development.
So, I've pretty much got the whole design of my app's card game down, I've solved it with a State Machine Design Pattern, I have a CardGame class which in itself manages the different states that the GameState Class can go through and the transitions between them.
Now, my problem is that I do not know how to merge this Design Pattern into my Android App. The main issue is that I can't figure out how to only show a certain Player the actions he can carry out at the certain State the game is at. For example, once the game has just begun, the first Player should only be able to choose 3 of the 15 actions (methods) that the CardGame class allows.
If it where a simple command driven program, once a player would choose an action that he could not execute at a certain time, the program itself would simple printout a "You cannot carry out this action right now, choose another one." or something of that sort, but being it an Android App that manages Buttons and their OnClickListeners, I certainly have not found it to be very easy. I would be grateful if anyone could orient me as to what a viable solution would be, if there is, of course, a way to solve this inconvenient.
Is there a way to manage what Buttons should be printed according to the availability of a certain State's methods? Can one use some sort of flag to notify what the unavailable methods are in any way?
Thanks in advance, Agustin.
Just use a set to store currently valid actions, and update the set (and redraw buttons) when relevant state is changed.

Pattern "One activity, multiple views": Advantages and disadvantages

This pattern is similar to the pattern Main Servlet (the Front Controller) that is used for developing web applications.
The main idea of this pattern: we have one Activity that manages multiple views and this activity is responsible for representing current content. Not all views need functional of activity (e.g. life-cycle methods) so the main question is: if I can go without activity why do I have to use it?
I have found the following disadvantages of using this pattern:
Official source doesn't recommend to Overload a Single Activity Screen
but they don't explain why.
We cannot use TabActivity, ListActivity, MapActivity. But there are some tricks to go without them.
If different screens have different menu it's a problem to make that without activities.
It is necessary to keep history by ourselves. But it's not so difficult to develop.
I have found the following advantages of using this pattern:
It's faster to change the content of current activity than to start another activity
We are free to manage history as we want
If we have only one activity-context it's simpler to find and solve problems with memory leaks
What do you think about this pattern ? Could you provide any other advantages/disadvantages ?
We cannot use TabActivity, ListAcivity, MapActivity. But there are some tricks to go without them.
You have to use MapActivity if you want to use MapView. You have to use PreferenceActivity if you want to use preference XML.
It is necessary to keep history by ourselves. But it's not so difficult to develop.
The difficulty in managing your own history will depend greatly on what the history needs to be. Implementing history for a simple wizard will be fairly easy. However, that is a particularly simple scenario. There is a fair amount of history management code in Android that you would have to rewrite for arbitrary other cases.
You also forgot:
#5. You will be prone to leak memory, because you will forget to clean up stuff, and Android will not clean up stuff (since it assumes that you will be using many small activities, the way they recommend).
#6. Your state management for configuration changes (rotation, dock, SIM change, locale change, multiple displays, font scale) will be more complicated because now you also have to figure out what extra stuff (e.g., history) need to be part of the state, and you have deal with all of them at once rather than activity-at-a-time.
#7. Having multiple entry points for your application becomes more challenging (e.g., multiple icons in launcher, app widget linking to some activity other than the main one, responding to etc.).
It's faster to change the content of current activity than to start another activity
For most modern Android devices, the speed difference will not be significant to most users, IMHO.
If we have only one activity-context it's simpler to find and solve problems with memory leaks
Except that you still have more than "one activity-context". Remember: your activity, large or small, is still destroyed and recreated on configuration changes.
What do you think about this pattern ?
Coase's "nature of the firm" theory says that businesses expand until the transaction costs for doing things internally become higher than the transaction costs for having other firms do the same things.
Murphy's "nature of the activity" theory says that the activity expands until the transaction costs of doing things internally become higher than the transaction costs for having other activities do the same things. Android developers will tend towards a "user transaction" model for activities -- things that are tightly coupled (e.g., steps in a wizard) will tend to be handled in single activity, and things that have little relationship (e.g., browse vs. search vs. settings vs. help vs. about) will tend to be handled in distinct activities.
This will be horrible to maintain if new functionality is added later on.
I'm also not convinced it will be so much faster that the user could notice.
Having components as smaller pieces that are easier to change or swap out is definitely the way to go.

Categories

Resources