在之前写过一篇执行后台耗时操作封装:http://blog.csdn.net/u010047390/article/details/43982461
这这篇文章中会有一个黄色提示:This Handler class should be static or leaks might occur
意思应该把这个handler定义成静态否则可能引起内存泄露。
我们再回顾前面的定义的方式:
Handler messageHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case UPDATE_UI: try { updateUI(); } catch (Exception e) { } break; default: break; } } }; 在这里我是直接用匿名内部类的方式去创建了一个类继承Handler,然后在这个类里面去执行了updateUI()方法。这个方法是属于外部类CommonHandle的,但是在内部类可以直接用,说明在这个类定义里隐含了一个外部类的引用。由于handler再消息队列中是存在引用的,生命周期可能长于CommonHandle这个类本身创建的实例需要的生命周期。<_>这里可能关于生命周期有点晕了,我们就考虑我们用到CommonHandle的一个场景,去后台取数据时,我们先创建了CommonHandle,然后在start的时候启动线程去执行handData里面的耗时操作了。按常理讲,我们预想的CommonHandle的生命周期要到取完数据,然后执行完updateUI之后再结束。但是在网络慢的时候,用户可能直接关闭这个界面了,这个时候,我们是不希望任何地方再握有CommonHandle的引用的,但是messageHandler因为是在消息队列中存在引用的,所以这个一直未释放。所以对这个类我现在做了一个改进,首先把这个匿名内部类定义成静态的,这样就不会直接引用外部类了,然后需要用到这个类是,在构造的时候传入这个引用,这个引用采用软应用的方式,在内存不足的时候可直接释放。
private MyHandler messageHandler = new MyHandler(this); /** * * <p>描 述:自定义处理UI更新类</p> * <p>创 建 人:william</p> * <p>创建时间:2017-1-17下午3:23:30</p> * */ static class MyHandler extends Handler { WeakReference<CommonHandle> hand; public MyHandler(CommonHandle commonHandler) { hand = new WeakReference<CommonHandle>(commonHandler); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case UPDATE_UI: try { if (hand.get() != null) { hand.get().updateUI(); } } catch (Exception e) { } break; default: break; } } };