一:简单用
1.0:用法
@SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.i("MainActivity",msg.toString());
//TODO
break;
}
}
};
Message mMessage = Message.obtain();
mMessage.what = 1;//标志
mMessage.obj = "data";
mHandler.sendMessage(mMessage);
注:Message mMessage = Message.obtain();,为啥这样写,看法宝
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
打印输出结果
MainActivity: { when=-24ms what=1 obj=data target=com.practicing.demo.MainActivity$1 }
二:优化
2.1.容易引起的问题
2.1.1 内存泄露
非静态内部类可以直接访问外部类的成员,反之不行。因为非静态内部类没有被static修饰,所以这个内部类就不是类相关的,也就说不是类的,是实例的,但是我们非静态内部类要创建实例,外部类一定会先创建一个外部类的实例,非静态内部类的实例就是寄生在外部类的实例上的。所以,非静态内部类的实例可以直接访问外部类的成员,因为,外部类已经创建一个实例的,内部类保留了外部类创建的实例的引用。静态内部类不一样!静态内部类是被static修饰的,所以是类的一员。根据静态成员不能访问非静态成员的原则,静态内部类是不能访问外部类的非静态成员的。非静态的内部类和匿名内部类都会隐式地持有其外部类的引用。一般情况会把Handler写成静态内部类。如果为非静态内部类,会引用外部类对象。Handler被Activity引用,当Activity finish以后,Handler仍未执行完毕,就会造成内存泄露。这就是 非静态内部类引用外部类对象造成内存泄露。
2.1.2 空指针异常
Activity 调用destory()方法之后,Handler的相关资源仍违背释放,然后就空指针喽
2.2:解决办法
2.2.1 内存泄露
- 放在单独的类中
这个没啥说的,就是创建一个新的类 - 弱引用
public class MyHandler extends Handler{
private final WeakReference<MainActivity> activityWeakReference;
public MyHandler(MainActivity activity) {
activityWeakReference = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
if (activityWeakReference.get() != null){
switch (msg.what) {
case 1:
Log.i("MainActivity","activityWeakReference:"+msg.toString());
//TODO
break;
}
}
}
}
调用部分
MyHandler myHandler = new MyHandler(this);
Message mMessageWeak = Message.obtain();
mMessageWeak.what = 1;
mMessageWeak.obj = "MyHandler";
myHandler.sendMessage(mMessageWeak);
2.2.2 空指针异常
把消息队列中的消息remove掉,具体做法就是在onDestroy()方法里面,调用removeCallbacks()方法,removeMessage()方法.