Thursday, May 5, 2016

Fixing ANR (Application not responding) in android

In this blog I want to talk about why ANR.I am giving details here why ANR come and how we prevent android application to ANR.

ANR (APPLICATION NOT RESPONDING) IN ANDROID:

If android application is not responding from long time it shows ANR dialog to ask user for wait or close application.
Android applications normally run entirely on a single thread by default the "UI thread" or "main thread"). This means anything your application is doing in the UI thread that takes a long time to complete can trigger the ANR dialog because your application is not giving itself a chance to handle the input event or intent broadcasts.

WHY ANR COMES IN APP?

There is few conditions in android that causes for ANR.
In Android, application responsiveness is monitored by the Activity Manager and Window Manager System services. Android will display the ANR dialog for a particular application when it detects one of the following conditions
     1) No response to an input event (such as key press or screen touch events) within 5 seconds
     2) BroadcastReceiver hasn't finished executing within 10 seconds.

HOW TO GET ANR?

Here I want to give a small example you can get ANR programmatically. Generally it comes due to small mistakes or bed programming hobbits. If you take care of coding then you can avoid ANR.
Here is an example of button that create ANR if user want to know how ANR is and what logs comes when ANR occurs

(Button).findViewById(R.id.button).setOnClickListener(new OnClickListener()
  {
    @Override
    public void onClick(final View v)
      {
      try
        {
        Thread.sleep(10000);
        }
      catch(final InterruptedException e)
        {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
      }
  });

PREVENTION OF ANR:

If developer keep taking care of few things then he is able to avoid or prevent ANR.

1)      Worker Thread:
The most effective way to create a worker thread for longer operations is with the AsyncTask class. Simply extend AsyncTask and implement the doInBackground() method to perform the work. To post progress changes to the user, you can call publishProgress(), which invokes the onProgressUpdate() callback method. From your implementation of onProgressUpdate() (which runs on the UI thread), you can notify the user.
Ex:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    // Do the long-running work in here
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return totalSize;
    }

    // This is called each time you call publishProgress()
    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    // This is called when doInBackground() is finished
    protected void onPostExecute(Long result) {
        showNotification("Downloaded " + result + " bytes");
    }
}
Execution syntax:
new DownloadFilesTask().execute(url1, url2, url3);

2)      If your application has a time-consuming initial setup phase, consider showing a splash screen or rendering the main view as quickly as possible, indicate that loading is in progress and fill the information asynchronously. In either case, you should indicate somehow that progress is being made, lest the user perceive that the application is frozen.

3)      For game development specifically, do calculations for moves in a worker thread.

4)      Use performance tools such as Systrace and Traceview to determine bottlenecks in your app's responsiveness.

HOW to FIX ANR?

For fixing ANR you will have to analyze your programs and correct the program if you are doing any long running task in main thread or broadcast receiver.
You can use StrictMode to help find potentially long running operations such as network or database operations that you might accidentally be doing on your main thread.


public void onCreate() {
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                           .detectAll()
                           .penaltyLog()
                           .penaltyDeath()
                           .build());
    super.onCreate();
}


Using penaltyLog() you can watch the output of adb logcat while you use your application to see the violations as they happen.
Hope this blog will help to resolve and identify ANR. If someone have more details which I did not mansion in blog so please post the sameJ.









19 comments:

  1. "Fixing ANR (Application Not Responding)" is a critical task in Android app development. How Make Minecraft ANR occurs when an Android application becomes unresponsive.

    ReplyDelete
  2. 1E1C9
    ----
    ----
    ----
    ----
    ----
    ----
    ----
    matadorbet
    ----

    ReplyDelete