这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
在上一章我们简单的介绍了handler的用法,包括message的传递和子线程通知主线程更新UI,接下来介绍一下常用的api和内存泄漏的问题。
1.常用api
Message message = Message.obtain();
//发送消息
new Handler().sendMessage(message);
//发送一个延时1s的消息
new Handler().sendMessageDelayed(message, 1000);
//发送一个带标记的消息(内部创建了message,并设置msg.what = 0x1)
new Handler().sendEmptyMessage(0x1);
//发送一个带标记的延时1s的消息
new Handler().sendEmptyMessageDelayed(0x1, 1000);
//发送一个延时1秒的消息(第二个参数为:相对系统开机时间的绝对时间,而SystemClock.uptimeMillis()是当前开机时间)
new Handler().sendMessageAtTime(message, SystemClock.uptimeMillis() + 1000);
2.handler使用避免内存泄露
为什么就会产生内存泄漏呢?
内存类会隐式的持有当前类的外部引用,Handler是非静态内部类持有当前Activity的隐式应用,Handler没有被释放的时候,Activity也不可能被释放,当GC回收这个Activity时,发现有一个正在使用的对象持有他的引用,无法释放内存,就会发现内存泄漏。
(1)怎么使用可能会导致内存泄漏
public class MainActivity extends AppCompatActivity {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.postDelayed(new Runnable() {
@Override
public void run() {
}
}, 1000 * 60);
}
}
activity被执行时,要发送的消息要在主线程中延迟一分钟发送,这个消息持有一个handler的引用, 但是它是由内部类创建的,还在隐式的持有着activity引用,不能正常释放而产生内存泄漏。
(2)怎么避免内存泄漏
public class MainActivity extends AppCompatActivity {
private static class MyHandler extends Handler{
private final WeakReference<MainActivity> mAct;
public MyHandler(MainActivity mainActivity){
mAct =new WeakReference<MainActivity>(mainActivity);
}
@Override
public void handleMessage(Message msg) {
MainActivity mainAct=mAct.get();
super.handleMessage(msg);
if(mainAct!=null){
}
}
}
private static final Runnable myRunnable = new Runnable() {
@Override
public void run() {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyHandler myHandler=new MyHandler(this);
myHandler.postDelayed(myRunnable, 1000 * 60 );
}
}