如果开发机器上出现问题,我们可以通过查看/data/anr/traces.txt即可,最新的ANR信息在最开始部分。
Service在特定的时间内无法处理完成 20秒
使用AsyncTask处理耗时IO操作。
使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREADPRIORITYBACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。
使用Handler处理工作线程结果,而不是使用Thread.wait()或者Thread.sleep()来阻塞主线程。
Activity的onCreate和onResume回调中尽量避免耗时的代码
BroadcastReceiver中onReceive代码也要尽量减少耗时,建议使用IntentService处理。
在Android里,应用程序的响应性是由Activity Manager和WindowManager系统服务监视的 。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR:
1.在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)2.BroadcastReceiver在10秒内没有执行完毕
如何去避免ANR呢?
1.避免在主线程执行耗时操作,比如io操作,数据库操作,图片处理等等
2.在BroadcastReceiver的onrecive里不要执行耗时操作,否则超过10秒就会导致ANR
今天在云测上偶现ANR事件, 如何去定位呢?
可以通过命令adb pull /data/anr/traces.txt . 获取ANR堆栈日志,然后查找日志里
以DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 NATIVE开头的日志,看下出错信息,就可以分析到ANR的原因了
cocos2d-x游戏项目androidproject接入sdk。支付成功后,java代码回调lua方法。产生了anr。
在data/anr/traces.txt文件里记录和anr错误信息。能够使用RE管理器查看该文件。
在日志信息中能够看到回调方法中调用的cocos2d-x的音频引擎播放音效的方法。就在这里产生了anr。我这里使用的是cocos2d-x2.1.5。
找到出问题的根源后,我把播放音效的代码凝视了。然后再执行。就没有产生anr了。
可是,还有一个问题又出现了...
报了一个OpenGL error,创建CCSprite也失败了。出现这种问题通常是由于CCSpirte没有在GL线程中创建。
主线程(ui thread):app启动时创建的线程。其他线程都是该线程的子线程。主要用于更新UI的线程。
GL线程:主线程的一个子线程。主要用于更新GUI的线程。在Cocos2d-x中,会从主线程中分出一个GL线程用于画面渲染相关的工作(为了保证画面的流畅)。
Android下。Activity有一个runOnUiThread方法。该方法用于在主线程中运行一个任务。
注意,假设该任务比較耗时会产生anr。
方法的声明例如以下:
public void runOnUiThread(Runnable task);
在Android下OpenGL的渲染须要与GLSurfaceView打交道。
所以Cocos2d-x封装了一个Cocos2dxGLSurfaceView。该View是与GL线程相关的。
Cocos2dxActivity中包括了一个Cocos2dxGLSurfaceView。并提供一个runOnGLThread方法。该方法用于在GL线程中运行一个任务。
方法声明例如以下:
public void runOnGLThread(final Runnable task);
实现上是调用了GLSurfaceView的queueEvent方法实现与GL线程通信。
实现机制还是Android下的消息轮询。
最后,通过runOnGLThread方法,在GL线程中回调lua方法。问题就彻底攻克了。
ctx.runOnGLThread(new Runnable() {
@Override
public void run() {
PayTools.payCallback(); //lua方法须要在GL线程中调用
}
});