Android App Development Practices

Some of the key technology and practices that we follow for Android development is given below

Android Studio – Android’s official website explicitly states “Android Studio is now the official IDE for Android”. 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.

Strings.xml – Adding text as String resources is always useful in the long-run especially when support for new languages need to be added. Create a separate layout for UI elements that will be re-used – The tag makes it possible to have a single layout, re-used across multiple activities and fragments.

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 be many xxxhdpi devices in the future. So, you should start developing a habit of including them.

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.

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.

Shapes and selectors – Basic shapes and gradients can easily be drawn using the 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.

Deep levels in layouts – Having a deep hierarchy of Views makes the UI slow, not to mention a harder to manage layout. Reflections recommends deep hierarchies can mostly be avoided by using the correct ViewGroup.

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.

HTTP library (ion, 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 ion and Retrofit reduce a lot of boilerplate code and we have less things to worry about.

Parcelable class – 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.

AsyncTaskLoader – 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.

File operations – 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.

Services – A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

Fragments – A Fragment represents a behavior or a portion of user interface in an Activity. Multiple fragments can be combined in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. We use fragments for achieving re-usable components in UI.

FCM – Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost. Using FCM, you can notify a client app that new email or other data is available to sync. You can send notification messages to drive user reengagement and retention.

Weak Coupling with UI – We structure the business logics to stay detached from UI components for scalability and maintainability of code. We use tools like ButterKnife to reference UI components to code.

Instrumentation and JUnit – We use instruments and JUnits to unit test small testable standalone modules or UI components using mock environments before merging with the master code.