神刀安全网

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

Looper、Message、Handler的关系

当我们的Android应用程序的进程一创建的时候,系统就给这个进程提供了一个Looper,Looper是一个死循环,它内部维护这个一个消息队列。Looper不停地从消息队列中取消息(Message),取到消息就发送给了Handler,最后Handler根据接收到的消息去修改UI。Handler的sendMessage方法就是将消息添加到消息队列中。 安卓核心基础知识梳理之Android消息处理机制

  1. 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异常

  1. 简介
    Application No Response:应用程序无响应。在主线程中,是不允许执行耗时的操作的,如果主线程阻塞的时间大于6秒,就很有可能出现anr异常。
    主线程,要完成界面的更新,事件的处理,窗体显示的回调,所以如果主线程阻塞时间较长,就不能很好的处理以上比较重要的事情,那么Android有一个机制,就是如果他发现消息队列中有很多消息,主线程没办法响应的话,他就会抛出anr异常。所以,比较耗时的操作都必须要交给子线程。
  2. 解决办法
    可以通过Handler来解决这个问题,将比较耗时的操作交给子线程,然后子线程通过Handler,发送消息给主线程,让主线程去更新界面。
    什么样的操作时比较耗时的?
    1、访问网络,2、大文件的拷贝,3、阻塞式的请求,socket
结合工作和面试
  1. 面试中

     ANR异常 (常问)

    为什么为出现ANR异常,如何解决?

     Handler机制 (这个非常重要) Looper、Message、MessageQueue、Hanler如何运作的?

  2. 工作中
    这个章节非常重要,工作中用的很多。工作中如果碰到ANR异常,根据异常日志,需要会解决。需要会使用handler进行线程间通讯。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 安卓核心基础知识梳理之Android消息处理机制

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址