What are ANR errors in Android and how to get rid of them?

ANR stands for “Application Not Responding”. It happens when main UI thread of your app is blocked.


The main reason why it happens is the time taking processes which run on main UI thread.
When the main UI thread is blocked by a time taking process, the app stops responding to user actions(i.e. clicks, scroll, etc.)
This provides a very bad user experience. To tackle this problem, you can run such long time taking processes like loading an image, downloading a file, running a timer, read/write from internal or external memory etc.
There are many techniques to handle this problem. But all of them process the time taking jobs into another thread except the main UI thread. So, the UI(User Interface) thread is not affected, and app can listen to user’s actions while the long time taking job is in progress on another thread. While the job is in progress, if user wants to quit the process or app, the app can listen to him easily without showing an ANR error.
To run jobs in another thread you can use the below code examples:
  1. Handler Implementation

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Handler mHandler;
     public void useHandler() {
       mHandler = new Handler();
       mHandler.postDelayed(mRunnable, 1000);
     }
    
     private Runnable mRunnable = new Runnable() {
    
       @Override
       public void run() {
         Log.e("Handlers", "Calls");
         /** Do something **/
         mHandler.postDelayed(mRunnable, 1000);
       }
     };
To cancel it

1
mHandler.removeCallbacks(mRunnable);

  1. AsyncTask Implementation

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    private class AsyncTaskRunner extends AsyncTask<String, String, String> {
    
        private String resp;
        ProgressDialog progressDialog;
    
        @Override
        protected String doInBackground(String... params) {
            publishProgress("Sleeping..."); // Calls onProgressUpdate()
            try {
                int time = Integer.parseInt(params[0])*1000;
    
                Thread.sleep(time);
                resp = "Slept for " + params[0] + " seconds";
            } catch (InterruptedException e) {
                e.printStackTrace();
                resp = e.getMessage();
            } catch (Exception e) {
                e.printStackTrace();
                resp = e.getMessage();
            }
            return resp;
        }
    
    
        @Override
        protected void onPostExecute(String result) {
            // execution of result of Long time consuming operation
            progressDialog.dismiss();
            finalResult.setText(result);
        }
    
    
        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(MainActivity.this,
                    "ProgressDialog",
                    "Wait for "+time.getText().toString()+ " seconds");
        }
    
    
        @Override
        protected void onProgressUpdate(String... text) {
            finalResult.setText(text[0]);
            
        }
    
    }
To run/start it

1
2
3
AsyncTaskRunner runner = new AsyncTaskRunner();
String sleepTime = time.getText().toString();
runner.execute(sleepTime);

You can tweak the above examples according to your needs and implement in your application.
Thanks for reading!

Comments