Let’s explore some best practices in designing and developing Android apps.
For starters, when you develop an Android application, you should prepare it to be run on a wide variety of devices and circumstances.
Every Android device is a family in itself. When one member of the family goes haywire, it means the rest of the family is also likely to be affected.
Did you know that when any single application asks for memory, if there isn’t any free memory, Android will respond by closing other apps so it can provide that memory? Then if the user switches to that application, it will have to be restarted.
When any single application takes up more memory, using more CPU and GPU, or consuming more battery, every other application suffers as a result. And this has the potential to wreck the user experience for the entire device.
If you want to learn more about Android performance, start here.
Here are some additional best practices you should follow when building Android apps:
- Use the recommended Android architecture.
Learn about the Android application architecture from here.
and from the following.
- Always maintain the code quality. Quality matters a lot. It’s not only about MVP/MVVM/MVC/etc., but also about each piece of code in each part of your app.
- Detecting and fixing memory leaks in android. Read this article to understand.
- Always include unit tests. This is the most important part of application development. I recommend running unit tests on the JVM, because it’s much faster than running them on the Android device itself or an emulator. If you require any android dependencies, use Robolectric. If you need to mock some objects while testing, use Mockito.
Use Dependency Injector to make testing easier.
- Always include functional UI tests. Functional tests check the functionality of your app from the user’s point of view. They launch your app and test its functionality. Here you can use Android Instrumentation if your application is not going to interact with other applications, as it runs only with your application. If there is an interaction with other apps use UIAutomator for testing this functionality.
- As I said earlier, Always write code for better performance.
Beware of little expenses. A small leak will sink a great ship. — Benjamin Franklin
- Use Proguard in your release version. This will remove all your unused code, which will reduce APK size.
- Use debugging tools. I highly recommend to use Android Debug Database . This library will be your best friend. Android Debug Database is a powerful library for debugging databases and shared preferences in Android applications. It’s a very simple tool for viewing databases and shared preferences directly in your browser.
- Use strings.xml. Adding text as string resources is always useful in the long-run, especially when support for new languages needs to be added.
- Create separate layouts for UI elements that will be re-used. Then use the include tag in xml. Another handy tag is the <merge/> tag. It acts as a pseudo parent, and helps get rid of an unneeded root ViewGroup. Read here about it.
- 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 on 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.
- Use shapes and selectors instead of images as much as possible. This further reduces APK size.
- Avoid deep levels in layouts. A deep hierarchy of views makes your UI slow, not to mention making it harder to manage your layouts. Deep hierarchies can mostly be avoided by using the correct ViewGroup. Use Constraint Layout.
- Use a HTTP library like Fast Android Networking, Volley, or Retrofit, depending on your use case.
- Use the Parcelable class instead of Serializable when passing data in Intents or Bundles. Serialization of an object that implements the Parcelable interface is much faster than using Java’s default serialization. A class that 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, you can selectively add data from the object to a Parcel using which the object is later deserialized.
- Perform file operations off the UI thread. File operations should always be performed on a worker thread, typically by using an AsyncTask/Loader. They take time, and if done on the UI thread can make the interface feel sluggish. In situations where they block the UI thread for 5 seconds, an Application Not Responding warning will be triggered and shown to the user.
- Understand Bitmaps. As it takes a huge amount of memory. can lead to OOM easily. Users love content! Especially when the content is well formatted and looks nice. Images, for instance, are extremely nice content, mainly due to their property of conveying a thousand words per image. They also consume a lot of memory. A lot of memory! — Learn From Here.
- Understand Context. Learn from here.
- Use styles to avoid duplicate attributes in layout XMLs.
- Use Fragment when it is required.
- Learn RxJava. RxJava is a Java VM implementation of Reactive Extensions. It has become the single most important skill for Android development.
- Learn the activity lifecycle.
- In general, use proven libraries instead of your own solutions.
- Learn How The Android Image Loading Library Glide and Fresco Works?
- Learn to create a pub/sub library.
- How to Learn Android Development.
And again, finally: Keep testing on various OS versions.
Do not develop for only one device. Develop for all devices.
Happy Learning 🙂