来自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());