如何正确自定义handler

来源:互联网 发布:淘宝部分店铺无法使用 编辑:程序博客网 时间:2024/04/30 16:54

来自DeskClock/src/com/android/deskclock/alarms/starclock/ui/BaseMediaListActivity.java的源码

问1、为什么是静态 2、为什么使用WeakReference保存一遍activity。

 54     private static class InnerHandler extends Handler { 

 55         private final WeakReference<BaseMediaListActivity> mActivity;
 56    
 57         public InnerHandler(BaseMediaListActivity activity) {
 58             this.mActivity = new WeakReference<BaseMediaListActivity>(activity);
 59         }
 60    
 61         @Override
 62         public void handleMessage(Message msg) {
 63             BaseMediaListActivity activity = mActivity.get();
 64             if (activity == null) {        
 65                 LogUtils.d("WeakReference of BaseMediaListActivity already has recycled.");
 66                 return;
 67             }
 68    
 69             switch (msg.what) {            
 70                 case BaseMediaListActivity.MSG_REQUEST_DATA_REQUEST:
 71                     activity.onStarRequest();      
 72                     break;
 73                 case BaseMediaListActivity.MSG_REQUEST_DATA_SUCCESS:
 74                     activity.onRequestSuccess((String) msg.obj);
 75                     break;
 76                 case BaseMediaListActivity.MSG_REQUEST_DATA_FAILED:
 77                     activity.onRequestFailed(msg.arg1, (Throwable) msg.obj);
 78                     break;
 79                 default:
 80                     throw new IllegalArgumentException("Invalid message type: " + msg.what);

 81             }

 82         }

 83     }

答1:因为使用了外部的静态变量,只能将handler定义为静态内部类,非静态内部类访问不到静态变量。

答2:如果不写构造函数,编译器解析内部类代码时,自动添加了够函数,传入外部类的对象,内部类一直支持外部类activity,容易引起内存溢出。

所以自定义handler时,应该着重注意,避免内部类直接,持有外部类对象,应该使用若引用方式持有。


如果handler中的looper也是自定义,问题2更容易引起内存泄漏。

所以在不使用loopr的时候主动退出。因为如果不主动退出looper,looper会一直存在。

如果反复创建,还会引起创建线程溢出。因为new HandlerThread("downloadImage");时,最终是在native层创建线程,

使用select,管理线程描述符,最大只能创建1024个(bionic/libc/include/sys/select.h 中有定义

正确使用:

650     private class SubThreadHandler extends Handler {                                                                                                                       
651         这里没有需要弱引用和静态的必要
652    
653         public SubThreadHandler(Looper looper) {
654             super(looper);
655         }
656    
657         public void handleMessage(Message msg) {
658    
659             switch (msg.what) {              
663                     if (null != mHandlerThread) {  
664                         boolean quit = mHandlerThread.quitSafely(); 
665                         LemeLog.printI(TAG, "mHandlerThread quit: " + quit);
666                     }
667                     break;
668             }
669         }
670     }


158         mHandlerThread = new HandlerThread("my");
160         mHandlerThread.start();
161         mSubThreadHandler = new SubThreadHandler(mHandlerThread.getLooper()); 


0 0