Android谨慎使用Handler

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执行任务。开发

相关文章
相关标签/搜索