Handler主要由2个用途。
一:用于延迟执行;
二:用于子线程更新UI操作。
一:延迟执行;
延迟方法列举:
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
比如启动画面到主页面的转换,可以在oncreat()方法里面写如下代码:
new Handler().postDelayed(new Runnable() { @Override public void run() { startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); } }, 2000);
二:子线程更新UI操作。
主要接受子线程发送的数据, 并用此数据配合主线程更新UI。
解释:当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作,例如: 联网读取数据, 或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。 这个时候,Handler就出现了。,来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程)
以下代码实现在子线程中更新UI功能,如果直接在子线程中tv.setText("");那是会报错的
private Handler handler = new Handler(){ public void handleMessage(Message msg){ switch(msg.what){ case updateProgress: tv.setText("已经被更新"); break; } } }; //子线程中代码 handler.sendEmptyMessage(updateProgress);
Handler中分发消息的一些方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
附:
Handler类的post和sendMessage或者sendEmptyMessage方法都会使得代码在UI线程中执行,只是post方法执行的代码是Runnable.run()方法,而sendMessage方法执行的是Handler.handleMessage方法
最后一点要说的就是handler非常适合用来做一些一直进行着的UI操作,比如播放歌曲时的进度条显示。只需要在handleMessage方法中再次调用sendMessage方法就可以形成一个循环然后持续不断更新啦。