Top

13 Android development best practices we follow at Innofied

android blog image

The popularity of Android has created a humongous demand for applications. As developers, it’s our responsibility to ensure that users don’t have a bad experience while using our apps. Here, at Innofied, there are a few Android development tips that we follow to ensure that our consumers/ clients get the optimum experience from the products. Lets take a look:

1. Switch to Android Studio

Android’s official website explicitly states “Android Studio is now the official IDE for Android”. If you’re still on Eclipse and that’s not enough reason to switch, here are few exclusive features of Android Studio that might change your mind:

  1. Android Studio uses the Gradle build system. Gradle has features like support for Maven repositories, multiple build types, multiple app flavors (for eg., demo & paid), apk splits (by screen density or ABI) & custom apk signing configurations.
  2. Contains built-in 9-patch creator.
  3. You can view previews for drawables, strings, colors & other resources.
  4. A color picker to pick colors in layouts and drawables.
  5. Almost all navigation & keyboard shortcuts from IntelliJ IDEA.

Furthermore, Google has ended development of the ADT plugin for Eclipse.

2. Use strings.xml

Adding text as String resources is always useful in the long-run especially when support for new languages need to be added.

3. Create a separate layout for UI elements that will be re-used

The <include /> tag makes it possible to have a single layout, re-used across multiple activities and fragments.
For example, for a uniquely styled button that must be shown in many activities of your application, a separate layout can be created. That layout can then be included in each activity’s layout.

 

Another handy tag is the <merge /> tag. It acts as a pseudo parent and helps get rid of an unneeded root ViewGroup.
For example, if your re-usable layout contains two Buttons placed vertically, you can put them inside a LinearLayout with vertical orientation. But this LinearLayout becomes redundant if the layout is included (using <include />) into another LinearLayout. In this case, our re-usable layout can have <merge /> as the root ViewGroup instead of LinearLayout.

4. Include resources for xxxhdpi screens

Many devices (and launcher apps) use launcher icons from the xxxhdpi drawable folder. Moreover, the LG G3 and Nexus 6 use all resources from xxxhdpi folders. There will definitely be many xxxhdpi devices in the future. So, you should start developing a habit of including them.

5. Place launcher icons in mipmap- folders

When building separate apks for different densities, drawable folders for other densities get stripped. This will make the icons appear blurry in devices that use launcher icons of higher density.
Since, mipmap folders do not get stripped, it’s always best to use them for including the launcher icons.

6. Use separate resources for debug and release

Gradle allows configuring custom build types. By default, two buildtypes, debug and release are provided.
We can provide separate files (source, resources & assets) for each build type by creating their corresponding folders, adjacent to the main folder, in the project structure. These folders follow the same structure as main & should contain only the overriding files.

An example of it’s usefulness is when you need to have a configuration file for Google Analytics. Separate xml files containing the Tracking ID can be created for both build types. During compilation, the file corresponding to the build will automatically be pulled.

Something to note here is that resource files/values from the main folder are always used. But a resource file/value in main will be overridden if it also exists in the build folder.

The image shows how to place the configuration file, ga_tracker.xml, for Google Analytics for debug and release build types.

  • ga_tracker.xml in debug contains a tracking Id for debugging purposes
  • ga_tracker.xml in release contains the actual tracking Id
  • ga_tracker.xml contains rest of the configuration

file_structure

7. Use shapes and selectors instead of images as much as possible

Basic shapes and gradients can easily be drawn using the <shape /> tag without the use of images. The resulting shapes that are drawn are always sharp and do not need to be created for multiple densities.

A basic circle can be created in the following way and saved as circle.xml in the drawables folder

The <selector /> tag can be used to add different visual states (like pressed, disabled, checked) to Views.

A simple selector, to add a pressed state background to a button, can be created in the following way and saved in the drawables folder

8. Avoid deep levels in layouts

Having a deep hierarchy of Views makes the UI slow, not to mention a harder to manage layout.

Deep hierarchies can mostly be avoided by using the correct ViewGroup.

For example, a view hierarchy like this:

layout

 

 

can be created in either of these ways:

OR

The second way should be preferred since it has a single level hierarchy.

9. Don’t add the whole Google Play Services library package

The Google Play Services library is a package that contains all the native Google libraries for android. Google also provides these libraries individually so that we can avoid adding the whole Google Play Services package. They can be added in build.gradle.

A list of the available libraries can be found here.

10. Use an HTTP library like Volley, Retrofit

When building a big application, our networking code can get huge because of boilerplate code. Not only does that make it difficult to maintain but also makes debugging harder. Libraries like Volley and Retrofit reduce a lot of boilerplate code and we have less things to worry about.

11. Use the Parcelable class instead of Serializable when passing data in Intents/Bundles

Serialization of an object that implements the Parcelable interface is much faster than using Java’s default serialization.

A class the implements the Serializable interface is marked as serializable and Java serializes it using reflection (which makes it slow).

When using the Parcelable interface, the whole object doesn’t get serialized automatically. Rather, we can selectively add data from the object to a Parcel using which the object is later deserialized.

12. Use an AsyncTaskLoader instead of an AsyncTask

A caveat while using an AsyncTask is that if the Activity gets destroyed before the AsyncTask has completed, it will still keep running and deliver the result in it’s onPostExecute() method, which could cause unexpected behaviour. A typical example of this situation is when a device is rotated while an AsyncTask is loading content.

Loaders were introduced in Honeycomb but can also be used in pre-Honeycomb versions using the support library.

Loaders are managed by a LoaderManager which is tied to the lifecycle of it’s Activity or Fragment. Each Activity or Fragment contains an instance of LoaderManager. If the Activity/Fragment is destroyed, the LoaderManager destroys the Loaders and frees up resources. In case of a configuration change, it retains it’s Loaders.

We can get a LoaderManger instance and initialize a Loader in the following way:

A simple AsyncTaskLoader can be created in the following way:

You might also want to override onStartLoading(), onForceLoad(), onReset(), onCancelled(), onStopLoading(), onAbandon(), cancelLoadInBackground(), onCancelLoad() according to your needs.

When calling the initLoader() method of a LoaderManager, we must pass an implementation of LoaderManager.LoaderCallbacks as the third parameter. It’s a callback for the events occurring in a Loader.

13. Perform file operations off the UI thread

File operations should always be performed on a worker thread typically using an AsyncTask/Loader. They take time and if done on the UI thread can make the interface feel sluggish. And in case it blocks the UI thread for 5 seconds, an ANR will be triggered.

 

These are some strong tips that one should always remember while developing an Android application. There are numerous other optimizations that can be done and many more that might be specific to your application. Following good practices not only makes it easier to manage and maintain your code but also reduces the number of potential bugs in your application.
If you have any questions don’t forget to drop them in the comments below.

Shubhadeep Chaudhuri

  • Hello,

    This is really an informative blog for all the beginners as well as app developers. App demand will surely increase day by day, as it is the main reason behind the business success. I love to develop apps for various platforms.

    I am an app developer, I have tried most of the mobile app development platforms. I have developed more than 50 apps till today with the help of Phonegap, Telerik, Configure.IT etc. They are running successfully on app store.

    As per my experience in this field, I recommend developers as well as beginners to use mobile app development platform like Configure.IT, because it provides automatic coding, app preview facility, direct API connect and a lot more features. These things save a lot more development time and provides fast and well designed app in much less time.

    Read more: http://www.configure.it/features/mobile-app-configuration/

  • Adit Lal

    Wonderful points to grasp and use

    • Shubhadeep Chaudhuri

      Thanks @Adit Lal

  • Pingback: Android & iOS Application Development | Just another My blog Sites site()

  • BruStack

    very useful, thank you

  • Jan Rabe

    I suggest using ReactiveX/RxAndroid over AsyncTaskLoader/AsyncTask

  • Hüseyin Barın

    Very good points and I just want to add one advise here look at square company’s open source projects not to reinvent wheel