How to improve android application performance and stability to go long way?

Sharing is caring!

Nowadays android application development is at the top of technologies. Many of the people are using an android phone. So, in this case as an android developer, we need to take care many things while developing an android application. An Android application should be faster, stable and less memory uses for best in a result. Actually, android performance is a lot of matter to work smoothly to go long business.

As an android developer needs to take care many things while developing the Android app, which we are going to discuss in this tutorial. So let’s get started that how to make an android application which performance is best in term of fast, less code and less memory use. Choosing the right algorithms and data structures should always be your priority and always try best coding practices that make your application faster and secure.

  • Why are memory leaks dangerous?

Actually memory leaks are happened because of bad code was written by developers. An application should not allocate memory if it can be possible to avoid. If any object holding the reference to unused Activity it creates the memory leaks. I have seen many of the places memory leaks is happened because of the used listener and did not remove it once activity gets destroyed. For example lets see an sample of add listener and remove listener.

public class LeakTestActivity extends Activity {

    //.................
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        AppManager.getInstance().addListener();
        
        //.........................
    }
}

Here in LeakTestActivity we have added listener but we have not removed this listener that cause of memory leak. So for best practice, we need to remove the listener once the activity gets destroyed.

public class LeakTestActivity extends Activity {

    //.................

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        AppManager.getInstance().addListner();

        //.........................
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        AppManager.getInstance().removeListener();
    }
}

In the other case, I have seen that people are using the handler to the passing message, that also creates the memory leaks when handler get delay to deliver the result and activity get destroyed same time. For the best practice, we should be used the weak reference.

public class LeakTestActivity extends Activity {

    //.................

    Handler mHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        mHandler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
            }
        };

    }
}

Here Handler is holding the reference to Activity. What happened if a message is postDelayed and the same time activity get destroyed because of memory is not available. If memory is not available android resource will kill your activity and application. But Handler is kept holding the reference to Activity which is not garbage collected by GC.

 mHandler.postDelayed()

So for best uses of handler try to use WeakRefernce to avoid a memory leak. This is a little bit tricky but we need to take care and understand the system.

  public static class MyHandler extends Handler{
        private final WeakReference<LeakTestActivity> mActivity;

        //................

        public MyHandler(LeakTestActivity leakTestActivity){
            mActivity = new WeakReference<LeakTestActivity>(activity);
            //.................

        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            
            //...................
        }
    }

These are few examples but It can be much more, I am not going into the deep here that What are the causes that will create the leaks. I have already explained in my last tutorial So I would be recommended to check Why is necessary to take care android memory leaks?

  • Use UI Thread only for UI.

This is also the most important case to slow performance because of we are given a lot of work on UI thread. So for best practice, we need to use UI thread only for UI. For example, in recyclerview or scroll view we used so many huge images to cache, it will create the application show.  Image cache and related kind of work should be in background thread not by UI thread.

So I recommend that you should not to do on UI Thread below kind of task. For example, Image caching and loading Networking operation, JSON Parsing, and Database access. To make android performance better and faster we should start to find the best version library to use.  You can use LRUCache for the cache which available in support library.

For Image Caching -> Glide, Picasso and Fesco etc.

For Networking/Async Http -> OkHttp, Volley, and Retrofit etc.

For JSON Parsing -> Parsing JSON has a performance effect and converted to class to getter setter is also create the performance issue. Recently Google has adopted the Kotlin because of getter and setter is kind of boilerplate code. If the JSON data is small then I would be recommended to pick the Google library GSON otherwise try to use JACSON or others library which gives the best performance result.

  • Concurrency API

Android provides the many concurrency API which we can use as per our requirement. For example Service, Intent Sevice, Async Task and AsyncTaskLoader, Looper, and Handler.

If you having the long operational tasks then please try to shift to execute by concurrency API. These kinds of the task should not execute by UI thread.

Service -> We can use service when we required for the long-running task to execute because it is independent of UI thread. Service can provide the parallel task execution if you want to execute the multiple services. It does not call stop service self you need to stop the service when your task has been completed.  For better performance of your application, I would always recommend using provided task ID and stop based on task Id, when your task has been completed by Service. You can check in detail Understanding Service in concurrency API.

IntentService -> Intent service is similar to Service but it is running with Single Thread and simple/one job at a time and no Job system to track the Job and no way to stop it. It will automatically be called stop method once the task has been completed. Generally, I would be recommended to use the Intent Service for a long-running task which is not effected on UI. For example, uploading file or image or video file and provide the notification once it is uploaded. You can check in detail Understanding Service in concurrency API.

Async Task and AsyncTaskLoader  -> We can use the Async task or AsyncTaskLoader for background operation by worker thread and result send back to the main thread to show data on UI Thread. Async Task doesn’t care about the result outside the UI. It can cause memory leak of Activity Lifecycle while rotating the app. Generally, I stopped using the Async Task because of a lot of limitation. I would be recommended to use the RxJava and RxAndroid for faster and best performance result. Please check the RxJava post here Basic Understanding of RxJava part1, Basic Understanding of RxJava part2.

When compare AsyncTaskLoader vs. AsyncTask, as you may know when you rotate your device screen, it may destroy and re-create your activity, to make it clear let rotate your device while networking transaction is going on:

AsyncTask will be re-executed as background thread again, and previous background thread processing was just redundant. AsyncTaskLoader will be just re-used basing on Loader ID that registered in Loader Manager before, so avoid re-executing network transaction. In summary, AsyncTaskLoader prevents duplication of background threads and eliminate duplication of zombie activities.

  • Deprecation & System Abuses

Please do not use code which is deprecated by Android API or library. Always try to use the latest API or code which gives you best result in term of performance. If any updated API comes or library please try to refactor your code. I have seen that many of the developers have used the deprecated API and not try to refactoring because of fear to change a lot of code and probably it will not be supported in your app which you did in past.

So I would be recommended to update the latest library version, API and IDE for better performance result and try to find the solution for best which suite for you and your app. You should always remember that things are deprecated because of new things comes and replace it because of gives the best result in terms of Security, correctness, and Performance. For example, show the list of data on Listview, switch ListView to RecyclerView. RecyclerView gives the best result in term of animation. So please be updated with updated library and API.

  • Architecture LifeCycle Component

Please understand the app component android LifeCycle for Activity, Fragment, Tasks, and Flag. Most of the developers are confused about the Lifecycle of Activity and Fragment. Sometimes we are not aware of lifecycle awareness to update the data which cause the memory leaks and app crash unnecessary.

Please try to use best Architecture design pattern like MVP, MVVM and recently given by Google Android Architecture. Your data update or change should be aware of lifecycle otherwise it will memory leak. If you are using the RxJava Observable sequence then make sure that it uses correct way because RxJava is not aware of Lifecycle. Always try to use LiveData and Databinding ObservaleField for the better result because they are aware of lifecycle event and avoid the memory leaks. Here is recommended post about the MVP RxJava for building an app.

Some of the Recommendations in term of Testing and Maintenance

  1. Try to use dependency Injection Dagger2 for better and faster Unit Test.
  2. Try to use UI test with Expresso.
  3. Try to use Mockito If you need to mock some objects while testing.
  4. Always try to write less code for best cases and try to use Lint code checker and find bug analyzer tool.
  5. Always try to refactor and reuse the code.
  6. Always make UI responsive to all devices and follow to use material design guidelines
  7. Make your apk less in size and try to use APK analyzer.
  8. Always use Crashlytics to find the crash of live users and fixed those.
  9. Try to use fewer dependencies and pick the dependency after good research that it will fit your requirement.
  10. Try to log with callback it gives a lot of memory leaks better to avoid as much as possible or updated with RxJava.
  11. Before writing the code, do some research and figure out which is best for performance. etc

Wrapping Up: I hope that all recommendation will help you to make your product for better in performance and attractive for users to the best result. If you have any recommendations feel free to give the suggestion for the comment below.

Please do subscribe email to get every newsletter on this blog and if you feel that this post will help you to better understand then do not forget to subscribe, share and comment below.

Happy coding 🙂

0 0 votes
Article Rating

Similar Posts

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Akash

Thoroughly put!