Java 静态内部类作用
需要了解2个概念:内部类和静态修饰符static
* 首先,用内部类是因为内部类所在的外部类有一定关系,往往2只有该外部类调用此内部类,所以没必要专门创建个类来承载。
* 静态都是用来修饰类的内部成员的,比如静态方法,静态成员变量,它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,所以可以用类名+静态成员名直接获得。
举个例子:
Car类有个叫wheel的内部类(非静态)
Car car = new Car();
car.wheel wheel = new car.wheel();
假如Car是内部静态类:
Car.wheel wheel = new Car.wheel;
内部类导致的内存泄漏问题:
* 常见的
public class SomeActivity {
// ......
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case 0:
// do something
break;
case 1:
// do something
break;
default:
break;
}
}
};
private void someMethod () {
mHandler.sendEmptyMessage(0);
}
}
上述代码中,mHandler字段指向一个匿名Handler类。匿名类是内部类,但是是特殊的内部类,如果把匿名类放到一个static方法中,它是不会持有外部类实例的。而在上面的代码中,这个mHandler会持有外部类(SomeActivity)实例的引用,因为它处于一个对象的上下文中,而不是类型上下文中。
当mHandler没有被回收时,其外围Activity对象不能被回收。当Activity被用户关闭(finish),而此时mHandler还未被回收,那么Activity对象就不会被回收,造成Activity内存泄露。
两种解决方式:
1:在关闭Activity时(finish/onStop等函数中),取消还在排队的Message:
mHandler.removeCallbacksAndMessages(null);2:使用WeakReference截断StrongReference。问题的症结既然是内部类持有外部类对象的引用,那我不用内部类就行了,直接使用静态成员类。但mHandler又需要与Activity对象交互,那就来个WeakReference,指向外部Activity对象。
public class SomeActivity {
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private WeakReference<SomeActivity> ref;
public MyHandler(SomeActivity activity) {
if (activity != null) {
ref = new WeakReference<SomeActivity>(activity);
}
}
@Override
public void handleMessage(Message msg) {
if (ref == null) {
return;
}
SomeActivity v = ref.get();
if (v == null) {
return;
}
// handle message
}
}
}