ANR(Application Not Responding)定义
在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。所以一个流畅的合理的应用程序中不能出现anr,而让用户每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样系统不会显示ANR给用户。默认情况下,在android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒。
ANR的避免方案:将耗时任务放入work thread。但在某些情况下,我们需要及时得到workthread的返回结果进行下一步的操作,这种情况下该怎么办呢?这里提供两种解决方案:
1、使用Callable 和 Future进行超时处理:demo如下
<pre name="code" class="java">private boolean checkNewCellProvider(){
boolean newCellInfoFlag = false;
if(Build.VERSION.SDK_INT>=17){
ExecutorService exec = Executors.newFixedThreadPool(1);
Callable<Boolean> call = new Callable<Boolean>() {
public Boolean call() throws Exception {
//开始执行耗时操作
CellInfo cellInfo = Cells.getCellInfoQuietly(mAppContext);
if(cellInfo != null)
return true;
else {
LogUtil.e(TAG, "SDK="+Build.VERSION.SDK_INT+"but get no cell");
return false;
}
}
};
try {
Future<Boolean> future = exec.submit(call);
newCellInfoFlag = future.get(500, TimeUnit.MILLISECONDS); //任务处理超时时间设为500毫秒
} catch (TimeoutException ex) {
newCellInfoFlag = false;
} catch (Exception e) {
newCellInfoFlag = false;
} finally{
// 关闭线程池
exec.shutdown();
}
}
return newCellInfoFlag;
}
<pre name="code" class="java">方案2:使用Countdownlatch
CountDownLatch latch = ExceptionReporter.postSingleError(AppContext.getInstance(mContext),ExceptionReporter.LOG_URL, error, mLocalPath + "/"+ filename);
try{
latch.await(500, TimeUnit.MILLISECONDS);
}catch (InterruptedException e1) {
e1.printStackTrace();
}
public synchronized static CountDownLatch postSingleError(
final AppContext context, final String url, final String data,
final String filepath) {
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
public void run() {
if (!sIsSending) {
sIsSending = true;
if (DEBUG) LogUtil.i(TAG, "start uploading error log");
processOldLogs(context, url,new File(filepath).getParentFile());
try {
String result = context.postSync(url, data.getBytes());
if (DEBUG) LogUtil.i(TAG, result);
} catch (Exception e) {
}
}
sIsSending = false;
latch.countDown();
}
}.start();
return latch;
}