A Single-Activity Android Application. Why not?!

Dmitriy Rabetckiy
@RosberryApps
Published in
7 min readJan 11, 2019

--

The reason behind writing this article was one of the I/O 2016 sessions where a speaker told about Google’s plans to neutralize the UX differences between Native Android App and Web. In its turn, availability of stable working libraries and my solid development experience finally served as a call to action. Though in all fairness, experience is not always the best motivator for making changes to the development process which has been ‘debugged to shine’.

Obvious Things about Activity

A basic Android application project can consist of one or more Activities. Activity may or may not contain Fragments. Fragment can include some UI that can be reused in an unspecified Activity or Fragment. It seems to be all logical and taken from the Bible. The question is: When should I create a new Activity? Let’s see what options we might have:

  1. An independent screen such as SettingsActivity which exists as one-off instance in the application.
  2. A screen that I can create as multiple instances, such as ProfileActivity.
  3. A screen that can be accessed using a Deep Link.
  4. A screen with unique settings of Status Bar, Navigation Bar and other window parameters.

Seems to be all, doesn’t it?

Based on our experience and the options above we can point out the following benefits (will reduce the development time and the number of bugs):

  1. Can set style for out-of-the-box screens using xml of Status Bar and Navigation Bar to input parameters.
  2. Built-in transition between screens.
  3. Can reuse or replace a previously launched Activity.

If there are advantages, then there should be some disadvantages as well. Let’s find out what they are.

  • One of the main drawbacks is asynchronous launch. No matter how ‘heavy’ your Activity is, Android will decide itself on what the delay should be before the launch.
  • The Shared Element Transition does not work between Fragment and Activity. That’s a bit of a headache when building complex UI/UX.
  • If screen layout is changed, the system re-creates screens for all previous Activities along with all the fragments relating to the backward navigation. By the way the same is true when restoring an app after it’s killed by the system.

Summarizing the above, the disadvantages can be brought down to a common denominator — the loss of control over the application by developer.

What you’re signing up for or taking control of it

Fragments do solve these problems, but also bring all the advantages that we’ve used to live with to nought! One has to pay in full for a complete control over the application whereas the chances of making a mistake are doubled. In addition to all the advantages of a Multiple-Activity which turn into disadvantages when you use a Single-Activity, you will have to solve the following tasks:

  1. Writing or selecting a library to navigate between screens.
  2. Breaking down the application into DI (Dependency Injection) modules and creating relations between them both for data transfer and semantically.
  3. Controlling UI of the main Activity depending on the state which the application is in.

If you have enough skills and proficiency, the estimate for developing an app will be one and half times higher in terms of the number of screens and their relationships between each other. That is, if you have 2 screens in the application and it takes 8 hours to implement them (layout, animations, saving state), then in a Single-Activity App the solution will require 12 hours as such.

Will I get those precious 60 fps?

Yes and no.

Animation smoothness between the screens will depend only on a smart arrangement of the views, their number as well as the data binding (text, pictures, audio, video). Messing up is only possible in the background. For example, one of the apps or services would take hold of the CPU or an I/O channel.

Activity or Fragment launching is practically the same under ideal circumstances. But you may ask why? Activity is actually “heavy” and has many properties and components. That’s all fine, but let’s get down the facts.

There are 3 measurable values that are absolutely important for us as they reflect the resource ‘efficiency’ of using an Activity or a Fragment.

  1. CPU Load
  2. Memory allocation
  3. Energy(battery) consumption

To get the above values, let’s use the Android Studio 3.2.1 Profiler and Battery Historian.

Analyze a screen with a typical layout that consists of: TextView, ImageView, Button, ProgressBar, and RecyclerView — and a default fadeIn/Out animation to render the transition between screens. It is important that it is drawn within ≤16 ms to maintain the experimental integrity.

Activity and Fragment content layout

Let’s analyze not only how an Activity or a Fragment becomes visible, but also their closing to simulate the user’s actions. Therefore, we will go through the following scenario.

Application Testing Algorithm

Running the scenarios with a Single and Multiple Activity several times we’ve obtained the following results from Battery Historian.

Multiple-Activity mode
Single-Activity mode

Battery percentage consumed for both runs are equal for our app. Not bad, actually, but on top of everything else we see that ANDROID_SYSTEM has consumed as much battery in the Multiple-Activity mode as our application itself. So far, 1:0 in favor of the Single-Activity.

Let’s measure other values using the Android Studio Profiler.

Single-Activity mode
Multiple-Activity mode

Energy. Multiple-Activity mode has performance close to perfect. It seems not a heavy work to just release allocated memory by closing Activity. You can see Battery Historian and Android Profiler results are diverged, but why is that? I think the cause is different calculation of power consumption parameters. Therefore it’s a contentions point what mode is better. Let us go further

CPU. It’s the major parameter which two times different from Single-Activity mode. A double CPU load difference manifests itself when we navigate backward. It shows that a Multiple-Activity wins in this case. Thanks to the stack of open Activities. The score is 1:1. In addition, if Multiple-Activity mode is efficient in terms of CPU usage then Energy consumption should be as well. The score 1:2.

Memory. In a Single-Activity mode there is an increase in memory allocation. Most likely this is due to memory leaks in the Fragments Backstack which we use to navigate backward. The score 1:3.

You can conduct your own research and make unbiased conclusions either based on your application or using my sample from the Github repository.

Conclusion

In this article I’ve compared two approaches to app navigation: Single and Multiple Activity. I’ve found some advantages and disadvantages of each of them. The tests revealed that Multiple-Activity mode is better in case of resources consumption. This means that we work fine all the time! Congrats!

But there is one meaningful reason to pay attention to Single-Activity App. UX of Single-Activity App is much better. I know the cost is high but the result is worth it.

To decide whether you can use a Single-Activity in your project or not, you should answer 3 questions:

  1. Will there be enough time to implement a Single-Activity Application?
  2. Is it possible to test the complete graph of transitions between screens?
  3. Will you save and restore the data and the states of the previously opened screens?

If you are all standing up for a Single-Activity Application, you will most likely be surprised at how much fun it is to use an application with impeccable responsiveness and to see seamless transitions between the screens. If you would like to be in the know as to what’s new in the Android realm, subscribe to our Telegram channel.

Below is the list of useful libraries in case you decide to implement a Single-Activity Application.

  1. Cicerone is a lightweight library that makes the navigation in Android app easier to implement
  2. Dagger 2 is a fast dependency injector for Android and Java.
  3. Moxy is an MVP Library for Android

--

--

Dmitriy Rabetckiy
@RosberryApps

Android Software Developer. Omsk, Russia, Earth, Milky Way