安卓开发ANR怎么处理

安卓开发ANR怎么处理,第1张

原因分析:android系统中处理用户 *** 作的工作时在主线程中执行的,如果我们的程序在主线程中进行一些耗时的 *** 作,导致用户的 *** 作6秒不能够处理,就会出现异常。

主线程休眠,那么再点击程序,必须等主线程睡醒后才会反应。

所以在主线程中不要做太耗时的工作,因为主界面会阻塞。

解决办法:让这些耗时的 *** 作放在新线程里面 *** 作。

注意:如果新线程里面做的事情要更新界面的话,就要使用handler来 *** 作。

连接网络的事都要放在新线程里面的。

解决代码(包括更新界面的 *** 作,使用的是handler):

import androidappActivity;

import androidosBundle;

import androidosHandler;

import androidviewView;

import androidwidgetTextView;

import androidwidgetToast;

public class MainActivity extends Activity {

private TextView numTV;

private Handler handler = new Handler();

private int i;

public void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

setContentView(Rlayoutmain);

numTV = (TextView) findViewById(RidnumTV);

}

public void doSomething(View view) throws Exception {

new Thread() {

public void run() {

for (i = 1; i < 20; i++) {

handlerpost(new Runnable() {

public void run() {

numTVsetText(i + "");

}

});

Systemoutprintln(i);

try {

Threadsleep(1000);

} catch (InterruptedException e) {

eprintStackTrace();

}

}

};

}start();

}

public void toast(View view) {

ToastmakeText(this, "十八大开幕了!", 0)show();

}

}

触发条件:单击Android系统控件Buttond出一个嵌入了WebView的PopupWindow时一切正常,而改用单击WebView加载的页面中的链接d出嵌入了另一个WebView的PopupWindow时则出现上述情况,程序随后强制关闭应用程序无响应-ANR。

Handler 是Android SDK中用来处理异步消息的核心类,子线程可以通过handler来通知主线程进行ui更新。

备注:本文源码截图 基于Android sdk 28

Handler机制 消息发送主要流程如图

应用程序启动后,zygote fork一个应用进程后,和普通java程序一样,程序会首先执行ActivityThread中的main函数。在main函数中,程序首先会创建Looper对象并绑定到主线程中,然后开启loop循环。(ps:主线程loop循环不能退出)

在prepareMainLooper方法中,最终会创建Looper,MessageQueue对象 以及创建native层MessageQueue对象。

使用HandlersendMessageXXX或这 postDedayXXX发送消息后,最终会调用到SendMessageAtTime方法中。

然后调用MessageQueueenqueueMessage将消息存到消息队列中。

存入消息后,然后通过调用native方法 唤醒主线程进行消息处理。

当应用程序启动,做完一些必要工作之后,便会开启Loop循环,除非系统异常,否则该循环不会停止。loop循环中,主要做两件事,第一,从消息队列中取消息。第二,进行消息分发处理。

MessageQueuenext() 方法 通过调用 native方法 nativePollOnce(ptr, nextPollTimeoutMillis)实现无消息处理时,进入阻塞的功能。

当nextPollTimeoutMillis 值为0时,该方法会立刻返回;

当nextPollTimeoutMillis 值为-1时,该方法会无限阻塞,直到被唤醒;

当nextPollTimeoutMillis 值大于0时,该方法会将该值设置为超时时间,阻塞到达一定时间后,返回;

在loop循环中 ,通过调用 msgtargetdispatchMessage(msg) 进行消息的分发处理

使用当前线程的MessageQueueaddIdleHandler方法可以在消息队列中添加一个IdelHandler。

当MessageQueue 阻塞时,即当前线程空闲时,会回调IdleHandler中的方法;

当IdelHandler接口返回false时,表示该IdelHandler只执行一次,

a,延迟执行

例如,当启动Activity时,需要延时执行一些 *** 作,以免启动过慢,我们常常使用以下方式延迟执行任务,但是在延迟时间上却不好控制。

其实,这时候使用IdelHandler 会更优雅

b,批量任务,任务密集,且只关注最终结果

例如,在开发一个IM类型的界面时,通常情况下,每次收到一个IM消息时,都会刷新一次界面,但是当短时间内, 收到多条消息时,就会刷新多次界面,容易造成卡顿,影响性能,此时就可以使用一个工作线程监听IM消息,在通过添加IdelHandler的方式通知界面刷新,避免短时间内多次刷新界面情况的发生。

在Android的消息机制中,其实有三种消息: 普通消息、异步消息及消息屏障。

消息屏障 也是一种消息,但是它的target为 null。可以通过MessageQueue中的postSyncBarrier方法发送一个消息屏障(该方法为私有,需要反射调用)。

在消息循环中,如果第一条消息就是屏障消息,就往后遍历,看看有没有异步消息:

如果没有,则无限休眠,等待被唤醒

如果有,就看离这个消息被触发时间还有多久,设置一个超时时间,继续休眠

异步消息 和普通消息一样,只不过它被设置setAsynchronous 为true。有了这个标志位,消息机制会对它有些特别的处理,我们稍后说。

所以 消息屏障和异步消息的作用 很明显,在设置消息屏障后,异步消息具有优先处理的权利。

这时候我们回顾将消息添加到消息队列中时,可以发现,其实并不是每一次添加消息时,都会唤醒线程。

当该消息插入到队列头时,会唤醒该线程;

当该消息没有插入到队列头,但队列头是屏障,且该消息是队列中 靠前的一个异步消息,则会唤醒线程,执行该消息;

调用MessageQueueremoveSyncBarrier 方法可以移除指定的消息屏障

ANR 即 Application Not Response, 是系统进程对应用行为的一种监控,如果应用程序没有在规定时间内完成任务的话,就会引起ANR。

ANR类型

Service Timeout : 前台服务20s, 后台服务200s

BroadcastQueue Timeout : 前台广播 10s,后台广播60s

ContentPrivider Timeout : 10s

InputDispatching Timeout : 5s

比如,在启动一个服务时, AMS端通过应用进程的Binder对象创建Service, 在scheduleCreateService()方法中 会调用到当前service的onCreate()生命周期函数;

bumpServiceExecutingLocked()方法内部实际上会调用到scheduleServiceTimeoutLocked()方法,发送一个ActivityManagerServiceSERVICE_TIMEOUT_MSG类型消息到AMS工作线程中。

消息的延时时间,如果是前台服务,延时20s, 如果是后台服务,延时200s;

如果Service的创建 工作在 上诉消息的延时时间内完成,则会移除该消息,

否则,在Handler正常收到这个消息后,就会进行服务超时处理,即d出ANR对话框。

复杂情况下,可能会频繁调用sendMessage 往消息队列中,添加消息,导致消息积压,造成卡顿,

1,重复消息过滤

频繁发送同类型消息时,有可能队列中之前的消息还没有处理,又发了一条相同类型的消息,更新之前的数据,这时候,可以采用移除前一个消息的方法,优化消息队列。

2,互斥消息取消

在发送消息时,优先将消息队列中还未处理的信息已经过时的消息 移除,优化队列

3,队列优化-复用消息

创建消息时,优先采用之前回收的消息,避免重复创建对象,引起GC

完~

(如果错误或不足,望指出, 大家共同进步)

以上就是关于安卓开发ANR怎么处理全部的内容,包括:安卓开发ANR怎么处理、WebView导致ANR问题,怎么解决、Android Handler那些事儿,消息屏障IdelHandlerANR等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9968907.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-03
下一篇2023-05-03

发表评论

登录后才能评论

评论列表(0条)

    保存