I am starting to develop an application for Android and was wondering what the common application design/structure looks like.
In iOS, I would generally start with a RootController which contains a UITabBarController and fill this with 4-5 UINavigationControllers. Each UINavigationController would contain its stack with UIViewControllers.
What would a similar application look like for Android?
Start reading here. The basic building block is an Activity, you setup your UI, display data and respond to events in your Activity classes. Screen navigation is handled by starting other activities using intents.
I lay out my activities and my activity xml files. Then I code in the components that are needed in the activity classes. Then I set up preferences and my submenu etc. From there I do my support classes and glue it all together.
Egil.. The Android way is significantly different from the iOS way in that it is more like a web interface.
First: "Activities" or UIs can be killed at any time. In fact, rotating the phone can kill an activity. So that each Activity needs to be able to save its state in onSaveInstanceState and restore state in onResume. Furthermore, "shared document like data" is written in onPause() and restored in onResume(). The closest analogy in iOS is saving state on low memory warning.
Second: Activities are relatively independent of each other so that state needs to be passed between Activities (UIs) using intents or saved globally using say Application state.
It is possible to quickly move an iOS TabBar to Android using Androids Options menu, but there is no built in hierarchy of views like UINavigationController.
I have a table comparing and contrasting iOS and Android here.
Take a look at Android Design in Action, they have great video lessons on how to design Android apps!
Related
With Jetpack Compose, is it a viable way to develop an app by having a single Activity only, and have Compose manage navigation between #Composables? When would it be necessary to add more Activities or Fragments?
Long version: I did some Android development years ago, where you would work with Activities and it was necessary to have multiple of them in any non-trivial app as they were the 'primitive' building blocks of every app. Then, Fragments came along and it was possible to host different ones within a single activity (they supported replacement etc. all with animations) and suddenly it was possible to implement the same app with fewer activities.
Years later, I'm back to Android development, this time with Jetpack Compose. I have already written an app with a couple of screens, using Jetpack Compose Navigation (https://developer.android.com/jetpack/compose/navigation), where #Composables are replaced and I'm very happy with by how much simpler everything has become. It seems that it is now possible to have an app with just a single activity, possibly without fragments either. I think that sometimes different activities might be necessary, e.g. if the application can process various Intents, but even then Compose Navigation supports stuff like deep linking etc.
With Jetpack Compose, is it a viable way to develop an app by having a single Activity only, and have Compose manage navigation between #Composables?
That is the theory. It remains to be proven for massive apps (think Facebook), but for small to mid-size apps, as far as we know, it should be fine.
Also note that the single-activity architecture pattern is not new to Compose UI — some developers have been going that route with fragments for the screens.
When would it be necessary to add more Activities or Fragments?
Assuming that we do not encounter some practical limit, the primary scenario for needing other activities and/or fragments would be for integration with framework classes or third-party libraries, where those external dependencies expect activities or fragments.
For example, app widgets can have a configuration activity. It is possible you could have your one-and-only activity handle that case too, but you might find it simpler to have a one-off small activity class just for the app widget configuration. That way, your main activity class does not get cluttered with logic for trying to distinguish between normal launches and app widget configuration launches. More generally, activities become entry points into your UI, and you probably only need as many activities as you want distinct entry points for different roles.
And, overall, "everything in moderation". If having something be implemented as a separate activity or fragment will help your app materially — ease of initial development, ease of maintenance, etc. — use it! Just because it is practical to have few activities does not mean it is bad to have more than one activity. We just now have even easier means of not forcing multiple activities where we might not need them.
I am developing a forum reader, which I expect that it will be run on phone only, not tablet.
The application originally have 3 views, and each is assigned with an Activity.
For example, if the user select a board on "Board selection screen", an Activity will start, and show the thread list of the selected board to the user.
Recently I have learned how to use fragment in an Android application. therefore I decided to convert my application from an Activity based apps to a Fragment based apps.
Although the apps works as fine as usual after the change, I encountered a problem in saving the state of the fragment. I failed to find the event to let me save the state of fragment (When I am switching from A fragment to B fragment). The most likely event is onSaveInstanceState(Bundle), but according to the API guide, it will only be called when an activity is about to be stopped, and it is not my case.
Actually I have tried to save the state in getArgument() in onDestroyView(). Nevertheless, according to the API guide, the values in getArgument() should only be used for instancing a fragment. Although everything work normal when I am saving the state in getArgument(), I believe that I am doing it wrong.
I have tried to do some googling about Fragment. I found that most of the artist suggest that Fragment is useful when an application is expected to run on both phone and tablet. And I don't find any artist that is talking about how to do screen switching between few Fragment within an Activity. I started to doubt that Fragment are only useful for supporting different device, but not for screen switching.
Sorry for the above junks. My questions are, does Fragment is not very useful when I am developing an application which for phone only? Should I change my application back to an Activity-based apps if I don't expect this to run on tablet?
One more thing Fragments are good at is they are good for Dialogs. Fragment-based dialogs have none of the problems you usually have with showDialog() when rotating the phone
No, you should stick with Fragments. They're incredibly versatile and will make your life easier down the road if you decide to rearrange things. As far as saving state, you just need to override onSaveInstanceState() in your Fragment (not the Activity). This will absolutely be called when switching between Fragments -- I use this all the time.
If we're talking about "just work" you can just go ahead and use fragments or just normal activities and layouts. However, what fragments provide, apart of scalability when developing for other devices like tablets, is that it's giving you more code separation, which is so, so great for the maintenance of the app.
I'm pretty much new to Android, but over the last two or three weeks I've managed to figure out most of its innards and how things work.
However, one thing is still bothering me - what's the basic difference between Activities and simple forms? Well, I know Android doesn't have such thing as a 'form', but by that I mean a fullscreen layout of elements that has an underlying class and all its functionality is executed in it, rather than in a process-wide class (Activity, to be precise).
As long as I understand, Activity is a separate process that's instantiated by OS to perform some actions that are basicly independent of the whole application. That also means that we can run only one of the application's activities, and it will still perform all of its functions without needing the whole application to be loaded. For example, if we have a movie player that can also convert movies from one codec to another, we can implement that functionality as a separate Activity so that other applications, like file managers, will also be able to convert movies between codecs using only that Activity, and not the whole application.
And that seems perfectly straightforward. The question is - why is everybody using separate Activities for functionality that cannot be separated from the application? In other words, people generally use Activities where I think simple forms within the same process would be more appropriate. For instance, I've seen people using a separate Activity for things like application settings, which obviously wouldn't be be launched outside the app itself, or editing application-specific data, which wouldn't be done outside the app as well, since the data to be edited should be selected from a list only known to the application.
Another example right from my experience - a unit converter application. It has a main menu with a GridView of units' categories, in each category there is a list of units and by clicking any unit we have a 'calculator' form for entering value that we want to convert. If I'd been doing that like everyone suggests I'd have three Activities - one for the main menu, one for the list of units and one for entering the value. But why? Why would I want to launch any of those three Activities separate from the application? If I'd want to launch main menu Activity - well, why not launch the whole application then? If I want just a list of units - again, just launch the whole application, it's not like some Facebook client is going to convert values between pressure units (since the list of units covers only one category at a time). And launching an activity for the calculator simply would not work, since it should return to the list to perform conversions and you'd have no list activity launched.
And anyway, even if I'm wrong and people use it wisely there's still an issue that Android SDK doesn't really provide any support for forms as I'm used to. Yes, there are things like ViewAnimator, ViewSwitcher etc. But all they do is switch layouts in their place, and that is hardly switching between forms as such. So the only choice to get close to that functionality at least is to use Activities. And we're back to the square one.
So to put it simply - am I missing something from the Android philosophy? Because I'm pretty sure that using a separate Activity (and a separate process as a result) for every single form in the application is an overkill. And if it really is and everybody knows that - why doesn't Android have any substantial form switching mechanism?
Thanks in advance for any clarification on this issue.
An activity isn't spawned in a separate process (unless you explicitly tell it to). Everything in your APK will be spawned in your process. Even if another application is using your Activity for whatever reason.
You can make your Activity "effectively" private to your application by not assigning any intent-filter to it in your manifest.
For the examples given, a form is equal to an activity. That isn't a universal statement as you delve deeper into Android, but for a beginner that's a decent analogy to make. Another common analogy is that Activities are more like web pages than traditional forms based UI.
I'm developing a rather GUI heavy android app and it has lots of little widgets (text fields, buttons etc..) which are dynamically configured at runtime. Everything is working well enough when the application has focus however once the user pushes the app to the background and restore it, all the widgets lose their dynamic state and revert back to their default state defined by their layout. Is this the proper behavior of Android apps?
I've developed numerous UIs on other platforms (iOS, Windows, Mac) and I've never seen behavior like this.. Do i have to do some magic dance to make Android keep the widgets state between re-focus? Any tips would be appreciated thanks!
What you need to do is to look at the lifecycle of an activity.
Basically, you need to save state in an onPause() function, and restore it with an onResume() function.
I am creating an android application that has a lot of different screens where the user can navigate to those screens using the buttons or list provided in those screens. What would be the best way to design the entire app's navigation flow? Should I map each screen to be View or an Activity? Can an design an entire android app with just one activity and many views, where each view represents one screen with many other UI elements (buttons, lists, images etc)
I suggest you use for every "screen" that is significantly different from another screen (in both look and data that it is related to) a new activity. This gives you easier control and you don't have to mess up your code with plenty of variables to define different states. Using different activites you usually shouldn't have to worry about running in a undesirable or even undefined state.
To exchange data between activities you can use putExtra() to add "simple" data to an INTENT or for more complex data you can extend Application and use that instance as a singleton, which you then can access via (MyApplication)getApplication();
You really want to stay away from the single activity idea. That's actually an anti-pattern from the java model 1 web application days called "The magic servlet". I guess here it would be called "The magic activity". Each logical "screen" that the user interacts with should be an instance of the Activity class.
Modifying individual user interface elements based on user interaction is fine as long as it's just one or two elements, or just a portion of the screen, but for the most part you should be looking for reasons to split things out into their own activities, not looking for reasons to keep things together. In the long run it will make your code easier to maintain and understand.