Android Introduction: General Design Considerations
Android Introduction: General Design Considerations
This whole section is taken from Professional Android Application Development book by Reto
Meier, with minor omissions, and it involves techniques and best practices when it comes to
developing for mobile devices in general, and for Android in particular.
Small and portable, mobile devices offer exciting opportunities for software development. Their
limited screen size and reduced memory, storage, and processor power are far less exciting, and
instead present some unique challenges.
It’s important to keep these restrictions in mind when creating new applications.
Be Efficient
Manufacturers of embedded devices, particularly mobile devices, value small size and long
battery life over potential improvements in processor speed. For developers, that means losing
the head start traditionally afforded thanks to Moore’s law. The yearly performance
improvements you’ll see in desktop and server hardware usually translate into smaller, more
power-efficient mobiles without much improvement in processor power.
In practice, this means that you always need to optimize your code so that it runs quickly and
responsively, assuming that hardware improvements over the lifetime of your software are
unlikely to do you any favors.
Since code efficiency is a big topic in software engineering, I’m not going to try and capture it
here. This chapter covers some Android-specific efficiency tips below, but for now, just note that
efficiency is particularly important for resource-constrained environments like mobile devices.
1
Advances in flash memory and solid-state disks have led to a dramatic increase in mobile-device
storage capacities (although people’s MP3 collections tend to expand to fill the available space).
In practice, most devices still offer relatively limited storage space for your applications. While
the compiled size of your application is a consideration, more important is ensuring that your
application is polite in its use of system resources.
You should carefully consider how you store your application data. To make life easier, you can
use the Android databases and Content Providers to persist, reuse, and share large quantities of
data. For smaller data storage, such as preferences or state settings, Android provides an
optimized framework.
Of course, these mechanisms won’t stop you from writing directly to the file system when you
want or need to, but in those circumstances, always consider how you’re structuring these files,
and ensure that yours is an efficient solution.
Part of being polite is cleaning up after yourself. Techniques like caching are useful for limiting
repetitive network lookups, but don’t leave files on the file system or records in a database when
they’re no longer needed.
The small size and portability of mobiles are a challenge for creating good interfaces,
particularly when users are demanding an increasingly striking and information-rich graphical
user experience.
Write your applications knowing that users will often only glance at the (small) screen. Make
your applications intuitive and easy to use by reducing the number of controls and putting the
most important information front and center.
If you’re planning to include touch-screen support (and if you’re not, you should be), you’ll need
to consider how touch input is going to affect your interface design. The time of the stylus has
passed; now it’s all about finger input, so make sure your Views are big enough to support
interaction using a finger on the screen.
Of course, mobile-phone resolutions and screen sizes are increasing, so it’s smart to design for
small screens, but also make sure your UIs scale.
The ability to incorporate some of the wealth of online information in your applications is
incredibly powerful.
2
The mobile Web unfortunately isn’t as fast, reliable, or readily available as we’d often like, so
when you’re developing your Internet-based applications, it’s best to assume that the network
connection will be slow, intermittent, and expensive. With unlimited 3G data plans and city-wide
Wi-Fi, this is changing, but designing for the worst case ensures that you always deliver a high-
standard user experience.
This also means making sure that your applications can handle losing (or not finding) a data
connection.
The Android Emulator lets you control the speed and latency of your network connection when
setting up an Eclipse launch configuration.
Experiment to ensure responsiveness no matter what the speed, latency, and availability of
network access. You might find that in some circumstances, it’s better to limit the functionality
of your application or reduce network lookups to cached bursts, based on the network
connection(s) available.
At What Cost?
If you’re a mobile owner, you know all too well that some of the more powerful features on your
mobile can literally come at a price. Services like SMS, GPS, and data transfer often incur an
additional tariff from your service provider.
It’s obvious why it’s important that any costs associated with functionality in your applications
are minimized, and that users are aware when an action they perform might result in them being
charged.
It’s a good approach to assume that there’s a cost associated with any action involving an
interaction with the outside world. Minimize interaction costs by the following:
Often the best solution is to use a lower-quality option that comes at a lower cost.
When using the location-based services, you can select a location provider based on whether
there is an associated cost. Within your location-based applications, consider giving users the
choice of lower cost or greater accuracy.
In some circumstances, costs are hard to define, or they’re different for different users. Charges
for services vary between service providers and user plans. While some people will have free
unlimited data transfers, others will have free SMS.
3
Rather than enforcing a particular technique based on which seems cheaper, consider letting your
users choose. For example, when downloading data from the Internet, you could ask users if they
want to use any network available or limit their transfers to only when they’re connected via Wi-
Fi.
You can’t assume that your users will think of your application as the most important feature of
their phones.
Generally, a mobile is first and foremost a phone, secondly an SMS and e-mail communicator,
thirdly a camera, and fourthly an MP3 player. The applications you write will most likely be in a
fifth category of “useful mobile tools.”
That’s not a bad thing — it’s in good company with others including Google Maps and the web
browser. That said, each user’s usage model will be different; some people will never use their
mobiles to listen to music, and some phones don’t include a camera, but the multitasking
principle inherent in a device as ubiquitous as it is indispensable is an important consideration
for usability design.
It’s also important to consider when and how your users will use your applications. People use
their mobiles all the time — on the train, walking down the street, or even while driving their
cars. You can’t make people use their phones appropriately, but you can make sure that your
applications don’t distract them any more than necessary.
What does this mean in terms of software design? Make sure that your application:
Is well behaved Start by ensuring that your Activities suspend when they’re not in the
foreground. Android triggers event handlers when your Activity is suspended or resumed
so you can pause UI updates and network lookups when your application isn’t visible —
there’s no point updating your UI if no one can see it. If you need to continue updating or
processing in the background, Android provides a Service class designed to run in the
background without the UI overheads.
Switches seamlessly from the background to the foreground With the multitasking
nature of mobile devices, it’s very likely that your applications will regularly switch into
and out of the background. When this happens, it’s important that they “come to life”
quickly and seamlessly. Android’s nondeterministic process management means that if
your application is in the background, there’s every chance it will get killed to free up
resources. This should be invisible to the user. You can ensure this by saving the
application state and queuing updates so that your users don’t notice a difference between
restarting and resuming your application. Switching back to it should be seamless with
users being shown the exact UI and application state they last saw.
Is polite Your application should never steal focus or interrupt a user’s current activity.
Use Notifications and Toasts instead to inform or remind users that their attention is
requested if your application isn’t in the foreground. There are several ways for mobile
devices to alert users. For example, when a call is coming in, your phone rings; when you
have unread messages, the LED fl ashes; and when you have new voice mail, a small
4
“mail” icon appears in your status bar. All these techniques and more are available
through the notification mechanism.
Presents a consistent user interface Your application is likely to be one of several in
use at any time, so it’s important that the UI you present is easy to use. Don’t force users
to interpret and relearn your application every time they load it. Using it should be
simple, easy, and obvious — particularly given the limited screen space and distracting
user environment.
Is responsive Responsiveness is one of the most important design considerations on a
mobile device. You’ve no doubt experienced the frustration of a “frozen” piece of
software; the multifunction nature of a mobile makes it even more annoying. With
possible delays due to slow and unreliable data connections, it’s important that your
application use worker threads and background services to keep your activities
responsive and, more importantly, stop them from preventing other applications from
responding in a timely manner.
Nothing covered so far is specific to Android; the design considerations above are just as
important when developing applications for any mobile. In addition to these general guidelines,
Android has some particular considerations.
To start with, it’s worth taking a few minutes to read Google’s Android design philosophy at
http://code.google.com/android/toolbox/philosophy.html.
Fast
Responsive
Secure
Seamless
In a resource-constrained environment, being fast means being efficient. A lot of what you
already know about writing efficient code will be just as effective in Android, but the limitations
of embedded systems and the use of the Dalvik VM mean you can’t take things for granted.
The smart bet for advice is to go to the source. The Android team has published some specific
guidance on writing efficient code for Android, so rather than rehash their advice, I suggest you
visit http://code.google.com/android/toolbox/performance.html and take note of their
suggestions.
You may find that some of these performance suggestions contradict established design
practices — for example, avoiding the use of internal setters and getters or preferring
virtual over interface. When writing software for resource-constrained systems like
embedded devices, there’s often a compromise between conventional design principles
and the demand for greater efficiency.
5
One of the keys to writing efficient Android code is to not carry over assumptions from desktop
and server environments to embedded devices.
At a time when 2 to 4 GB of memory is standard for most desktop and server rigs, even
advanced smartphones are lucky to feature 32 MB of RAM. With memory such a scarce
commodity, you need to take special care to use it efficiently. This means thinking about how
you use the stack and heap, limiting object creation, and being aware of how variable scope
affects memory use.
Being Responsive
Android enforces responsiveness with the Activity Manager and Window Manager. If either
service detects an unresponsive application, it will display the unambiguous Application
unresponsive (AUR) message. This alert is modal, steals focus, and won’t go away until you hit
a button or your application starts responding — it’s pretty much the last thing you ever want to
confront a user with.
An application must respond to any user action, such as a key press or screen touch,
within 5 seconds.
A Broadcast Receiver must return from its onReceive handler within 10 seconds.
The most likely culprits for causing unresponsiveness are network lookups, complex processing
(such as calculating game moves), and fi le I/O. There are a number of ways to ensure that these
actions don’t exceed the responsiveness conditions, in particular, using services and worker
threads.
The AUR dialog is a last resort of usability; the generous 5-second limit is a worst-case
scenario, not a benchmark to aim for. Users will notice a regular pause of anything more
than half a second between key press and action. Happily, a side effect of the efficient
code you’re already writing will be faster, more responsive applications.