Handler 作为 Android 经常使用组件之一,几乎每一个应用程序都会使用。Handler 主要有两个做用,一是当咱们须要按照顺序执行多个程序时,二是当咱们在非主线程中更新UI的时候。java
当咱们须要经过 Handler 执行一段代码时,可使用 post(Runnable)
, postAtTime(java.lang.Runnable, long)
, postDelayed(Runnable, Object, long)
加入一个Runnable
, 或者是使用sendEmptyMessage(int)
, sendMessage(Message)
, sendMessageAtTime(Message, long)
, sendMessageDelayed(Message, long)
发送Message
。但它们最终都会加入一个 MessageQueue
中,而后由 MessageQueue
所在的线程执行。oop
Handler
之因此能工做,是由于有 Looper
, 一个线程最多只能有一个 Looper
, 也能够没有。在建立 Handler
的时候,能够指定 Looper
, 也能够不指定,若是不指定则默认使用当前线程的 Looper
, 固然前提是当前线程有Looper
, 若是没有,则建立Handler
会抛出异常,而主线程默认是有 Looper
的。post
须要注意的是,加入 Handler 的任务不会当即执行,若是 Hander 中 Looper 所在线程当前正忙,则可能要等到这个线程不忙的时候才会执行经过 Handler 加入的任务。有些开发人员在开发的时候,会把全部须要主线程执行的任务都经过Handler加入,即便当前已是在主线程中了,是的,就是在主线中经过Handler加入一个须要在主线程中执行的任务,而又指望能加入的任务能当即执行,但恐指望会落空。由于正如上面所说,加入Handler的任务可能并不会当即执行,这要取决于当地主线程是否在忙。大多数状况下,主线程是比较空闲的,一般咱们只在更新UI的时候才会用到主线程,可是在一些较为复杂的项目中,就连开发者本身也不清楚主线程在干什么,他们只有在发现系统卡顿的时候才会去关心主线程。spa
为了不上面这种状况,其实也很简单,咱们只要判断当前线程是否主线程,若是是就当即执行,不然才加入Handler。线程
在主线程中运行的例子:code
private void runOnMainThread(Runnable runnable) {
if (Looper.myLooper() == Looper.getMainLooper()) {
runnable.run();
} else {
mHandler.post(runnable);
}
}
复制代码
Android 程序经常要处理UI,若是本应该当即更新的UI,却延迟了几十甚至上百毫秒,势必形成用户体验降低。因此在开发的时候要特别注意,尽可能不要在UI线程处理后台任务,而在UI线程中的任务要尽可能及时处理,特别是要避免已经在UI线程中了,还经过Handler执行任务。开发