Handler是什么:
Handler是Android提供给我们的用来更新UI的一套机制,也是一套消息处理机制,我们可以通过它发送消息,也可以通过它处理消息!
Handler的用法:
post(Runable):
handler.postDelayed(Runnable,long)
这是一种可以创建多线程消息的函数
使用方法:
1,首先创建一个Handler对象
Handler handler=new Handler();
2,然后创建一个Runnable对象
Runnable runnable=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
handler.postDelayed(this, 2000);
}
};
3,使用PostDelayed方法,两秒后调用此Runnable对象
handler.postDelayed(runnable, 2000);
实际上也就实现了一个2s的一个定时器
4,如果想要关闭此定时器,可以这样操作
handler.removeCallbacks(runnable);
当然,你也可以做一个闹钟提醒延时的函数试试,比如,先用MediaPlayer播放闹钟声音,
如果不想起,被停止播放之后,下次就5分钟后再播放,再被停止的话,下次就4分钟后播放,
只要更改延时的时间就可以实现了,用一个static对象的话会比较容易操作。
是可以异步效果,但Runnable的执行是在Handler对象所在的线程
如果其所在的线程是UI线程的话,Runnable中还是不能执行耗时操作,不然会ANR
前几天我们自己的设备很卡,卡到跳转界面都需要不到1秒的时间,我就把跳转的动作放在Runnable里边,外边加上弹出进度提示框
注:举例说明
传递Message:
sendMessage(RunnAble);
sendMessagePostDeayed(RunnAble,lone);
Handler.Callback()拦截消息回调:
Android为什么要设计只能通过Handlerde 方式跟新UI:
Handler的原理:
HandlerThread:
HandlerThread能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。(线程中的Looper)需要注意的是,新建的时候需要被回调。
HandlerThread的特点:
HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。
HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。
Handler的用法:
public class MainActivityextends Activity {
private HandlerThreadmyHandlerThread ;
private Handlerhandler ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建一个线程,线程名字:handler-thread
myHandlerThread =new HandlerThread("handler-thread");
//开启一个线程
myHandlerThread.start();
//在这个线程中创建一个handler对象
handler =new Handler(myHandlerThread.getLooper() ){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这个方法是运行在 handler-thread 线程中的 ,可以执行耗时操作
Log.d("handler " , "消息: " + msg.what +" 线程: " + Thread.currentThread().getName() );
}
};
//在主线程给handler发送消息
handler.sendEmptyMessage(1 );
new Thread(new Runnable() {
@Override
public void run() {
//在子线程给handler发送数据
handler.sendEmptyMessage(2 );
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
//释放资源
myHandlerThread.quit();
}
}
handler引起的内存泄漏以及解决办法
原因:静态内部类持有外部类的匿名引用,导致外部activity无法释放
解决办法:handler内部持有外部activity得到弱引用,并把handler改为静态内部类,mHandler.removeCallback();