Http://www.jianshu.com/p/8964812972be
Http://stackoverflow.com/questions/704311/android-how-do-i-investigate-an-anr
Keeping Your App Responsivepreviousnextin This document
- What Triggers ANR?
- How to Avoid Anrs
- Reinforcing responsiveness
You should also read
- Background Optimizations
- Intelligent job-scheduling
- Manipulating broadcast receivers on Demand
- Intents and Intent Filters
Figure 1. An ANR dialog displayed to the user.
It ' s possible to write code this wins every performance test in the world, but still feels sluggish, hang or freeze for Si Gnificant periods, or take too long to process input. The worst thing that can happen to your app's responsiveness is a "application not Responding" (ANR) dialog.
In Android, the system guards against applications that is insufficiently responsive for a period of time by displaying a dialog that says your app have stopped responding, such as the dialog in Figure 1. At this point, your app have been unresponsive for a considerable period of time so the system offers the user an option to Quit the app. It ' s critical to design responsiveness into your application so the system never displays a ANR dialog to the user.
This document describes how the Android system determines whether an application are not responding and provides guidelines For ensuring that your application stays responsive.
What Triggers ANR?
Generally, the system displays an ANR if a application cannot respond to user input. For example, if-application blocks on some I/O operation (frequently a network access) on the UI thread so the system C An ' t process incoming user input events. Or perhaps the app spends too much time building an elaborate in-memory structure or computing the next move in a game on The UI thread. It's always important-make sure these computations is efficient, but even the most efficient code still takes time to Run.
In all situation in which your apps performs a potentially lengthy operation, you should not perform the work on the UI Thread, but instead create a worker thread and does most of the work there. This keeps the UI thread (which drives the user interface event loop) running and prevents the system from concluding that Your code has frozen. Because Such threading usually is accomplished at the class level, you can think of responsiveness as a class pro Blem. (Compare this with the basic code performance, which is a method-level concern.)
In Android, application responsiveness are monitored by the Activity Manager and Window Manager system services. Android would display the ANR dialog for a particular application when it detects one of the following conditions:
- No response to a input event (such as key press or screen touch events) within 5 seconds.
- A
BroadcastReceiver
hasn ' t finished executing within seconds.
How to Avoid Anrs
Android applications normally run entirely on a single thread by default the "UI thread" or "main thread"). This means anything your application are doing in the UI thread that takes a long time to complete can trigger the ANR dial OG because your application is not giving itself a chance to handle the input event or intent broadcasts.
Therefore, any method, the runs in the UI thread should does as little work as possible on the thread. In particular, activities should does as little as possible to set up in key life-cycle methods such as onCreate (
and onresume ()
. Potentially long running operations such as network or database operations, or computationally expensive calculations such As resizing bitmaps should be do in a worker thread (or in the case of databases operations, via an asynchronous reques T).
The most effective-to-create a worker thread for longer operations are with the AsyncTask
class. Simply extend and implement the method to perform the work AsyncTask
doInBackground()
. To post progress changes to the user, you can call publishProgress()
, which invokes the onProgressUpdate()
callback method. From your implementation onProgressUpdate()
of (which runs in the UI thread), you can notify the user. For example:
Private Class Downloadfilestask Extends Asynctask<Url, Integer, Long> {
Do the long-running
Protected LongDoinbackground(Url...URLs) {
IntCount=URLs.Length;
LongTotalSize= 0;
For (IntI= 0;I<Count;I++) {
TotalSize+= Downloader.DownloadFile(URLs[I]);
Publishprogress((Int) ((I/ (Float)Count) * 100));
Escape early if Cancel () is called
If (IsCancelled()) Break;
}
ReturnTotalSize;
}
Called each time publishprogress ()
Protected voidOnprogressupdate(Integer...Progress) {
Setprogresspercent(Progress[0]);
}
/ /This was called when Doinbackground () is Finished
protected void Onpostexecute (long< Span class= "PLN" > Result) {
Shownotification ( "downloaded" + result + "bytes"
}
}
To execute the This worker thread, simply create a instance and call execute()
:
Newdownloadfilestask(). Execute(url1, url2, url3);
Although it ' s more complicated than asynctask
, you might want to instead create your own T Hread
or handlerthread
class. If you do, you should set the thread priority to ' background ' priority by CALLING&NBSP; process.setthreadpriority () and passing thread_priority_background
. If you don't set the thread to a lower the "this", then the thread could still slow down your app because it Operat Es at the same priority as the UI thread by default.
If you implement Thread
or handlerthread
, being sure that your UI Thread does Not block while waiting for the worker thread to complete-do not call thread.wait ()
or thread . Sleep ()
. Instead of blocking while waiting for a worker thread to complete, your main thread should provide a handler for the other threads-to-post to upon completion. Designing your application in this would allow your app's UI thread to remain responsive to input and thus avoid ANR di Alogs caused by the 5 second input event timeout.
The specific constraint on broadcastreceiver
execution time emphasizes what broadcast Receivers is meant to do:small, discrete amounts of work in the background such as saving a setting or registering A&nbs P Notification
. So as with other methods called in the UI thread, applications should avoid potentially long-running operations or Calcula tions in a broadcast receiver. But instead of doing intensive tasks via worker threads, your application should start an intentservice
& Nbsp;if a potentially long running action needs to being taken in response to an intent broadcast.
Another common issue with BroadcastReceiver
objects occurs when they execute too frequently. Frequent background execution can reduce the amount of memory available to other apps. For more information about what to enable and disable BroadcastReceiver
objects efficiently, seemanipulating broadcast receivers on Dem and.
Tip: You can use the Help StrictMode
find potentially long running operations such as network or database operations so you might a Ccidentally is doing on your main thread.
Reinforce responsiveness
Generally, the 200ms is the threshold beyond which users would perceive slowness in an application. As such, here is some additional tips beyond what you should does to avoid ANR and make your application seem responsive to Users
- If your application is doing work in the background in response to user input, show this progress is being made (such as W ith A in
ProgressBar
your UI).
- For games specifically, does calculations for moves in a worker thread.
- If your application have a time-consuming initial setup phase, consider showing a splash screen or rendering the main view As quickly as possible, indicate that loading are in progress and fill the information asynchronously. In either case, you should indicate somehow that progress are being made, lest the user perceive that the application is FR Ozen.
- Use performance tools such as Systrace and Traceview to determine bottlenecks in your app ' s responsiveness.
Android ANR Analysis (iii)