安卓核心基础知识梳理之Android消息处理机制

Looper、Message、Handler的关系 当我们的Android应用程序的进程一创建的时候,系统就给这个进程提供了一个Looper,Looper是一个死循环,它内部维护这个一个消息队列。Looper不停地从消息队列中取消息(Message),取到消息就发送给了Handler,最后Handler根据接收到的消息去修改UI。Handler的sendMessage方法就是将消息添加到消息队列中。 runOnUiThread Activity中提供了一个runOnUiThread方法,用于进行消息处理。此方法是通过线程合并——join来实现消息处理的。 线程合并:主线程将子线程的任务拿到自己这里来执行并终止子线程。 实例代码如下: /** * Runs the specified action on the UI thread. If the current thread is * the UI thread, then the action is executed immediately. If the * current thread is not the UI thread, the action is posted to the * event queue of the UI thread. * 上面的意思为:在UI线程中运行我们的任务,如果当前线程是UI线程,则立即执行,如果不是则该任务发送到UI线程的事件队列。 */ runOnUiThread(new Runnable() { @Override public void run() { //自定义我们的业务代码 } }); **postDelayed** 该方法是Handler对象提供的,Handler给消息队列发送一个消息,发送成功则返回true,否则返回false,如果返回false一般是由于looper进程不存在导致的。该方法主要用于定时任务。如果返回true也不一定代表着我们的定时任务就执行了,因为很可能在定时任务的时间未到之前我们的looper进程退出了,那么消息也就丢失了。 执行该任务的线程用的就是Handler对象所在的线程。 /** * Causes the Runnable r to be added to the message queue, to be run * after the specified amount of time elapses. The runnable will be run * on the thread to which this handler is attached. Parameters: r The * Runnable that will be executed. delayMillis The delay (in * milliseconds) until the Runnable will be executed. Returns: Returns * true if the Runnable was successfully placed in to the message queue. * Returns false on failure, usually because the looper processing the * message queue is exiting. Note that a result of true does not mean * the Runnable will be processed -- if the looper is quit before the * delivery time of the message occurs then the message will be dropped. * 上面代码翻译如下: * 该方法将一个Runnable对象r添加到消息队列,在指定的时间后会被执行。 * 这个Runnable对象会运行在当前handler所在的线程中。 * 第一个参数:Runnable 要执行的任务 * 第二个参数:delayMillis(单位:毫秒) runnable 任务被执行前的延迟时间 * 返回值:boolean ,如果该Runnable被成功添加到消息队列则返回true,否则返回false * 不过,通常返回false是因为looper进程处理消息队列退出。 * 注意:返回true不代表着Runnable被执行,如果looper在延时任务还没被执行前退出了,那么消息就丢失掉了。 */ boolean flag = handler.postDelayed(new Runnable() { @Override public void run() { } }, 2000); postAtTime 该方法也属于Handler对象,唯一不同的是该方法设置的定时任务是一个绝对时间,指的是Android系统的开机时间,如果想设置从当前时间算起2秒后执行该任务则可以将时间这样写:SystemClock.uptimeMillis()+2000,其中SystemClock.uptimeMillis()是系统运行时间。 /** * Causes the Runnable r to be added to the message queue, to be run at * a specific time given by uptimeMillis. The time-base is * android.os.SystemClock.uptimeMillis. The runnable will be run on the * thread to which this handler is attached. Parameters: r The Runnable * that will be executed. uptimeMillis The absolute time at which the * callback should run, using the android.os.SystemClock.uptimeMillis * time-base. Returns: Returns true if the Runnable was successfully * placed in to the message queue. Returns false on failure, usually * because the looper processing the message queue is exiting. Note that * a result of true does not mean the Runnable will be processed -- if * the looper is quit before the delivery time of the message occurs * then the message will be dropped. * 意译:给消息队列发出一个消息,让指定的任务在指定的时间执行。这里的时间是绝对时间,是相对于android.os.SystemClock.uptimeMillis的时间 * 如果我们想在当前时间的2秒后执行该任务则将时间设置为:SystemClock.uptimeMillis()+2000即可。 */ boolean postAtTime = handler.postAtTime(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }, SystemClock.uptimeMillis()+2000); } ANR异常 简介 Application No Response:应用程序无响应。在主线程中,是不允许执行耗时的操作的,如果主线程阻塞的时间大于6秒,就很有可能出现anr异常。 主线程,要完成界面的更新,事件的处理,窗体显示的回调,所以如果主线程阻塞时间较长,就不能很好的处理以上比较重要的事情,那么Android有一个机制,就是如果他发现消息队列中有很多消息,主线程没办法响应的话,他就会抛出anr异常。所以,比较耗时的操作都必须要交给子线程。 解决办法 可以通过Handler来解决这个问题,将比较耗时的操作交给子线程,然后子线程通过Handler,发送消息给主线程,让主线程去更新界面。 什么样的操作时比较耗时的? 1、访问网络,2、大文件的拷贝,3、阻塞式的请求,socket 结合工作和面试 面试中  ANR异常 (常问) 为什么为出现ANR异常,如何解决?  Handler机制 (这个非常重要) Looper、Message、MessageQueue、Hanler如何运作的? 工作中 这个章节非常重要,工作中用的很多。工作中如果碰到ANR异常,根据异常日志,需要会解决。需要会使用handler进行线程间通讯。

链接:http://www.imooc.com/article/8757

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值