美文网首页
笔记:Handler

笔记:Handler

作者: 逍遥天_lpc | 来源:发表于2017-01-15 19:48 被阅读0次

我一般创建Handler 是这样创建的

Handler handler = new Handler(new Handler.Callback() { 
   @Override    
    public boolean handleMessage(Message msg) {      
    Log.i("lpc", "----" + Thread.currentThread().getId() + "");    
    return false;    
}});
handler.sendEmptyMessage(0);

这样写法在主线程是没问题的

但如果在子线程中这样些就会报错

new Thread(new Runnable() {    
  @Override    
  public void run() {         
  Handler handler = new Handler(new Handler.Callback() { 
       @Override            
       boolean handleMessage(Message msg) {  
       Log.i("lpc", "----" + Thread.currentThread().getId() + ""); 
       return false;            
       }        
  });        
  handler.sendEmptyMessage(0);         
}}).start();

原因是源码中有这样一句

mLooper = Looper.myLooper();
if (mLooper == null) {    
    throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()");
}

也就是说mLooper为空导致的,需要在实例化Handler之前加上

Looper.prepare();

但是就很疑惑,在主线程中创建的Handler是在什么时候prepare的呢,最终原来是在ActivityThread中有这样一段代码

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ...
    Looper.loop();
}

prepareMainLooper方法

public static void prepareMainLooper() {    
    prepare(false);    
    synchronized (Looper.class) {        
    if (sMainLooper != null) {            
        throw new IllegalStateException("The main Looper has already been prepared.");        
    }        
    sMainLooper = myLooper();   
}}

ok,加上prepare方法后但是收不到消息,怎么回事?原来还需加上

Looper.loop();

为什么呢,这就需要看下Looper.loop的代码了

public static void loop() {
    final Looper me = myLooper();
    ...
    final MessageQueue queue = me.mQueue;
    ...
    for (;;) {    
        Message msg = queue.next(); // might block   
        ....
        msg.target.dispatchMessage(msg);
   }
}

因为默认的是主线程的looper,即me对象,一直循环取的也是主线程中的MessageQueue对象,所以如果是子线程的情况,需要主动调用下loop方法才行。

在Handler中有send和post方法,这两个有什么区别呢

send方法和post方法实际上最终都会走到这个方法里面

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {   
   MessageQueue queue = mQueue;    
    if (queue == null) {        
    RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
    Log.w("Looper", e.getMessage(), e);       
    return false;    
}   
   return enqueueMessage(queue, msg, uptimeMillis);
}

区别是在这里

public final boolean post(Runnable r){   
    return  sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {    
    Message m = Message.obtain();    
    m.callback = r;    
    return m;
}

实际上也是一个Message对象,只不过他的callback的值就是传入的Runnable,然后在Looper的loop方法中有这样一句代码

msg.target.dispatchMessage(msg);

所以最终会走到

public void dispatchMessage(Message msg) {    
    if (msg.callback != null) {        
        handleCallback(msg);    
    } else {
        if (mCallback != null) {            
              if (mCallback.handleMessage(msg)) {
                 return;           
               }        
        }        
        handleMessage(msg);    
    }
}

handleCallBack方法

private static void handleCallback(Message message) {  
     message.callback.run();
}

实际上只是执行了run方法,所以post方法能够实现UI的更新。但是注意,这并不是绝对的,run方法的执行是在创建此Handler的线程,而这不一定就是主线程。

相关文章

  • Handler机制小结

    Handler笔记 什么是handler机制?handler机制的主要成员1、handler:负责发送处理消息2、...

  • 2018-08-27

    Handler,Looper,Messagequeue,message学习笔记 Handler作为android线...

  • 【安卓学习笔记】AsyncTask异步任务

    要点: 安卓处理异步任务两种方法:Handler、AsyncTask。Handler在前一篇笔记中已经记录。相对来...

  • Android Handler 从使用到进阶

    1.Handler 只要是开发Android的同学,Handler这个经常都会看到,也会使用到,本文章就做个笔记。...

  • 笔记:Handler

    我一般创建Handler 是这样创建的 这样写法在主线程是没问题的 但如果在子线程中这样些就会报错 原因是源码中有...

  • Handler笔记

    1、数据通信会带来什么开发中的问题?(1)线程间如何进行通信Handler通信实现的方案实际上是内存共享方案。(2...

  • Handler 消息机制

    说起Handler机制大家都不陌生,我也看过不少网上相关文章,都分析的很好,这里作为笔记,通过Handler,Lo...

  • Handler机制与注意

    关于Handler可能很多初学者有疑问,根据个人的经验整理了下面的笔记,希望能给大家有所帮助 什么是Handler...

  • Handler.removeCallbacks(Runnable

    仅作为开发时的笔记记录 前言 平时使用 Handler.removeCallbacks(Runnable r) 比...

  • android handler笔记

    背景 Handler是android中比较重要的机制,是日常开发中也会经常遇到。另外,也是面试过程中必问的问题之一...

网友评论

      本文标题:笔记:Handler

      本文链接:https://www.haomeiwen.com/subject/iaaybttx.html