消息机制之Handler

来源:互联网 发布:php办公管理系统 编辑:程序博客网 时间:2024/06/14 08:54

一、Handler类在源码的android.os包下面,它主要用于消息的发送和处理,注意:这里的消息可以是线程,即:Handler可以处理普通消息和含有线程的消息。 
1、普通消息处理: 
Java代码  收藏代码
  1. mHandler.sendMessage(Message msg);  
  2. mHandler.sendEmptyMessage(int msg.what);  

sendEmptyMessage发送一个空消息,即没有消息数据;最终在Handler类里面都是调用了系统的sendMessageDelayed方法; 

2、线程处理: 
Java代码  收藏代码
  1. mHandler.post(Runnable r);  


3、带有Delayed或AtTime后缀的方法: 
这一类方法在Handler中最终都是统一按AtTime进行执行,具体处理方式: 
Java代码  收藏代码
  1. public final boolean sendMessageDelayed(Message msg, long delayMillis)  
  2.     {  
  3.         if (delayMillis < 0) {  
  4.             delayMillis = 0;  
  5.         }  
  6.         return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);  
  7.     }  


二、Handler的创建: 

1、构造方法有四个: 
Java代码  收藏代码
  1. public Handler(){}  
  2. public Handler(Callback callback) {}  
  3. public Handler(Looper looper) {}  
  4. public Handler(Looper looper, Callback callback){}  


2、一般实现形式: 

Java代码  收藏代码
  1. static Handler mHandler = new Handler(Looper.getMainLooper()) {  
  2.     public void handleMessage(Message msg) {  
  3.         switch (msg.what) {  
  4.         case 0:  
  5.             Log.i(TAG, "--方法一:实例化Handler--");  
  6.             break;  
  7.         }  
  8.     };  
  9. };  
  10.   
  11. static Handler mHandler1 = new Handler(new Handler.Callback() {  
  12.   
  13.     @Override  
  14.     public boolean handleMessage(Message msg) {  
  15.         switch (msg.what) {  
  16.         case 0:  
  17.             Log.i(TAG, "--方法二:添加回调接口--");  
  18.             break;  
  19.         }  
  20.         return false;  
  21.     }  
  22. });  
  23.   
  24. static class MainHandler extends Handler{  
  25.     @Override  
  26.     public void handleMessage(Message msg) {  
  27.         switch (msg.what) {  
  28.         case 0:  
  29.             Log.i(TAG, "--方法三:集成Handler类,覆盖handleMessage方法--");  
  30.             break;  
  31.         }  
  32.     }  
  33. }  


在实例化Handler时系统会提示: 
The following Handler class should be static or leaks might occur 
意思是说:Handler应该定义为静态的,否则可能会有泄漏产生; 

具体是这样的: 
Java代码  收藏代码
  1. if (FIND_POTENTIAL_LEAKS) {  
  2.             final Class<? extends Handler> klass = getClass();  
  3.             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&  
  4.                     (klass.getModifiers() & Modifier.STATIC) == 0) {  
  5.                 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +  
  6.                     klass.getCanonicalName());  
  7.             }  
  8.         }  


解释:同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static那么使用Handler的Service和Activity就也无法被回收。这就可能导致内存泄露。这为什么会产生呢?因为MessageQueue是阻塞式的,即:一个处理完才处理下一个,如果你MessageQueue中有一些延时的操作,整个MessageQueue的生命周期就很长,可能超过了定义Handler所在的Service和Activity的生命周期; 


三、消息处理: 
在上一篇消息机制之Looper中说的,Looper会不停的调用dispatchMessage给Handler分发消息,那最终还是调用了Handler的handleMessage方法处理消息,而handleMessage是有我们程序员重写的方法。 
Java代码  收藏代码
  1. public void dispatchMessage(Message msg) {  
  2.     if (msg.callback != null) {  
  3.         handleCallback(msg);  
  4.     } else {  
  5.         if (mCallback != null) {  
  6.             if (mCallback.handleMessage(msg)) {  
  7.                 return;  
  8.             }  
  9.         }  
  10.         handleMessage(msg);  
  11.     }  
  12. }  


到这儿,Handler基本搞清楚,是不是感觉Handler很绕,通过Handler把Message发给系统,系统最后又调用我们写的handleMessage方法把消息传过来,让我们处理,这不瞎折腾嘛? 
个人理解:由系统统一封装、排队、分发消息; 
0 0
原创粉丝点击