概述
最近一个程序报错,查看LOG才知道是ANR错误,提示原因为
ANR的英文全称为Application not Response,就是说程序没有影响异常,此异常导致的根本原因有两种:
1、onCreate方法中执行时长超过5秒,程序其他操作不能进行
2、BroadcastReceiver接收广播时,超过10秒没有响应,其他操作无法进行
此两种异常为Android系统本身所定的处理时长,因此如果Activity中有一些费时操作,一定要避免。
可能触发ANR的情况:
- 长时间的I/O处理,比如读写大文件,网络访问时造成的阻塞。
- 执行耗时的运算,Android默认为超过5000ms即5秒开始弹出ANR窗口,某些应用可能首次执行时没有缓存十分耗时,可以通过Splash播放闪屏Logo等方式来延缓加载。
- Service和appWidget中也要注意多线程的使用,除非它和Activity工作在不同的进程。
避免ANR的方法:
1、用AsyncTask异步任务类处理(极力推荐),AsyncTask类为Android本身提供的,已经过封装,非常好用,示例代码如下:
private class GetDataTask extends AsyncTask{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
String result = null;
if("wx".equals(bind)){
final HttpClient httpClient = SSLSocketFactoryEx.getNewHttpClient();
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
+ Constants.weixinAPPID + "&secret="
+ Constants.weixinSecretKey + "&code=" +params[0]
+ "&grant_type=authorization_code";
final HttpGet get = new HttpGet(url);
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(get);
String json = EntityUtils
.toString(httpResponse.getEntity());
Log.e("hupeng", "===微信获取数据===" + json);
result=getWeixinUserInfo(json);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭连接 ,释放资源
httpClient.getConnectionManager().shutdown();
}
}else if("sina".equals(bind)){
mAccessToken = AccessTokenKeeper.readAccessToken(BandAccountActivity.this);
// 获取用户信息接口
sinaUid = Long.parseLong(mAccessToken.getUid());
sinaToken=mAccessToken.getToken();
Log.e("hupeng", "===新浪WeiboAuthListener===唯一id:"+sinaUid+"===mAccessToken==="+mAccessToken);
final HttpClient httpClient = SSLSocketFactoryEx.getNewHttpClient();
String url = "https://api.weibo.com/2/users/show.json?access_token="+sinaToken+"&uid="+sinaUid;
final HttpGet get = new HttpGet(url);
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(get);
result = EntityUtils.toString(httpResponse.getEntity());
Log.e("hupeng", "===新浪微博获取数据===" + result);
} catch (Exception e) {
e.printStackTrace();
handler.obtainMessage(9,"授权错误!").sendToTarget();
} finally {
// 关闭连接 ,释放资源
httpClient.getConnectionManager().shutdown();
}
}
return result;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if("wx".equals(bind)){
JSONObject wxSendJson = new JSONObject();
JSONObject weixinJson;
try {
weixinJson = new JSONObject(result);
wxSendJson.put("bindtype", "2");// 1qq,2微信,3微博
wxSendJson.put("openid", weixinJson.get("openid"));// 用户唯一id
wxSendJson.put("access_tocken", wxToken);
wxSendJson.put("openkey", "");
wxSendJson.put("type", "1");
weixinOpenid=(String) weixinJson.get("openid");
wxSendJson.put("sessionid", Constants.userInfo.userSession);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("hupeng", "===微信用户信息===已成功向服务器发送微信绑定请求===" + result);
otherBind(wxSendJson, Constants.WEIXINLOGIN);// 绑定
}else if("sina".equals(bind)){
JSONObject json = new JSONObject();
try {
json.put("bindtype", "3");// 1qq,2微信,3微博
json.put("openid", sinaUid);// 用户唯一id
json.put("access_tocken", sinaToken);
json.put("openkey", "");
json.put("type", "1");
weiboOpenid=sinaUid+"";
json.put("sessionid", Constants.userInfo.userSession);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("hupeng", "===新浪用户信息===已成功向服务器发送微信绑定请求===" + json.toString());
otherBind(json, Constants.WEIBOLOGIN);// 绑定
}
}
}
2、单独开工作者线程,通过独立的Thread,如果线程比较多,可以用ExecutorService进行管理,也非常好用,示例代码如下:
ExecutorService pool = Executors.newFixedThreadPool(2);
//创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
Thread t1 = new MyThread();
Thread t2 = new MyThread();
Thread t3 = new MyThread();
Thread t4 = new MyThread();
Thread t5 = new MyThread();
//将线程放入池中进行执行
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
3、耗时的操作尽量分段处理,使用类似状态机的方法,类似Symbian的活动对象将一个复杂的事情,分段执行,这是一种非常好的思路,可以将一大段非常长的耗时操作分为多段执行
4、UI线程中不要处理过多的内容,比如将一个5MB的文本,让TextView去setText,要知道这种UI操作,没有什么好方法去解决的,所以遇到UI中需要执行复杂的操作,可以参考上面3提到的分段处理方式。
还有个要注意的地方,当发生ANR错误时,具体代码出错记录会保存在data/anr/traces.txt里,可进行细节查看。
最后
以上就是感动小霸王为你收集整理的ANR错误之 keyDispatchingTimedOut的全部内容,希望文章能够帮你解决ANR错误之 keyDispatchingTimedOut所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复