You are on page 1of 2

ANR — Application Not Responding

What’s it?

First of all ANR means Application Not Responding. I guess it’s very clear about what it is. No need to explain.

When Happens?
According to Google’s documentation for Android, we are given two cases for an ANR to happen.

1. If there is no response for an input event for 5 seconds then it’s going to be an ANR. (For instance you press a key on
keyboard and there is no response for 5 seconds)

2. Secondly, assume that you have a BroadcastReceiver. By the time it receives a broadcast, it has 10 seconds to finish
it’s execution. Otherwise it’s going to be an ANR also.

How To Avoid It?


Stop doing heavy jobs on main thread. Instead use worker threads such as IntentService, AsyncTask or another Thread.

Where To Look For ANR?

 The app is doing slow operations on main thread. (Including I/O)

 App is doing a long calculation on main thread.

 The main thread is doing a synchronous binder call to another process and that process is doing a heavy job.

 The main thread is blocked waiting for another process which is doing a long job.

 The main thread is in a deadlock with another thread.

How To Solve?
Strict Mode

On the development phase you can use Strict Mode to identify accidental I/O operations.

Developer Options

Actually not all ANR’s are shown to user. But at Developer Options of Settings, there is an option “Show All ANRs”. If this
option is selected, Android OS will show you internal ANRs also.

TraceView

Android Studio has an inbuilt tool called TraceView. You can see memory and CPU usage of your app. For how to user
TracevView, please refer to here.

Inspect Traces File


When ANR happens, Android logs some info related to the case in a txt file on device itself. You can use ADB to gather logs
and have a look. Just use theese commands.

adb root
adb shell
cat /data/anr/traces.txt

An Example
Let’s indicate a commonly occurring case for ANR. We do a sorting job inside of a button click event. May it be like:

@Override
public void onClick(View view) {
// This task runs on the main thread.
BubbleSort.sort(data);
}

In such a case what we need to do is to remove sorting process into a worker thread. Luckily Android has provided us some
methods of multi-threading. Please refer to helper classes for threading.

@Override
public void onClick(View view) {
// The long-running operation is run on a worker thread
new AsyncTask<Integer[], Integer, Long>() {
@Override
protected Long doInBackground(Integer[]... params) {
BubbleSort.sort(params[0]);
}
}.execute(data);
}

An Example Of Log
An example of ANR would be good. Please notice the line in bold....
AsyncTask #2" prio=5 tid=18 Runnable
| group="main" sCount=0 dsCount=0 obj=0x12c333a0 self=0x94c87100
| sysTid=25287 nice=10 cgrp=default sched=0/0 handle=0x94b80920
| state=R schedstat=( 0 0 0 ) utm=757 stm=0 core=3 HZ=100
| stack=0x94a7e000-0x94a80000 stackSize=1038KB
| held mutexes= "mutator lock"(shared held)
at com.android.developer.anrsample.BubbleSort.sort(BubbleSort.java:8)
at com.android.developer.anrsample.MainActivity$LockTask.doInBackground(MainActivity.java:147)
- locked <0x083105ee> (a java.lang.Boolean)
at com.android.developer.anrsample.MainActivity$LockTask.doInBackground(MainActivity.java:135)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
...

You might also like