很多面试题问到“子线程中能否创建Handler?”。
之前一直使用HandlerThread框架,在主线程中创建与子线程关联的Handler实例,也没考虑过这个问题。
代码如下:
HandlerThread mHandlerThread = new HandlerThread("Controller Message Processing Thread");
mHandlerThread.start();
Looper mServiceLooper = mHandlerThread.getLooper();
Handler mMessageHandler = new Handler(mServiceLooper) {
@Override
public void handleMessage(Message msg) {
}
};
针对“子线程中能否创建 Handler实例?”基本上就是说直接new Handler()无参数实例,
看源码,使用无参构造函数时确实有抛出异常的可能:
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
}
结论:在创建Handler之前,必须在子线程中调用Looper.prepare(),否则就抛出异常。
总觉得这样的面试题有些傻x,考察点难道就是如上的结论?
可是完全也没必要非得在子线程中创建Handler实例啊,在主线程完全可以完成所有的事情,解决所有的问题,完全可以不去踩这个坑的,你踩过一次坑,别人必须也得踩过才是熟练使用,没踩过就就是大笨蛋?
得出结论:这类面试题说明你踩过的坑别人没踩过就是蠢货......
其实主要就是考察你对他们区别的理解。
http://www.cnblogs.com/xgjblog/p/5258947.html
主线程会默认创建一个Looper,所以在主线程中创建handler时,不会报错,
而子线程中没有默认创建Looper,所以在子线程中创建handler 时,会报错,提示需要调用Looper.prepare(),方法在子线程创建一个Looper
好好去理解handler Looper MessageQueue 的关系吧
可以参考一下我的博客 http://blog.csdn.net/ganyao939543405/article/details/52438180
完整解析了 Android 消息框架的源码,源码加了很多注解。
简单的说 普通 Thread 和 handlerThread 区别就是 HandlerThread
run() {
while(isOn) {
if () {
Runnable runnable = null;
if (runnable = hasMessage() //这里没有消息会阻塞) {
handlerThreadRun(runnable);
}
}
}
仅仅是封装了一下而已
你自己在普通线程里面 Looper.looer() 是一样的效果
handler的作用就是在子线程中更新主线程UI,如果你只会在主线程中创建handler用处大吗?特殊情况下比如只给子线程你,让你直接post一个接口更新主线程,你怎么办?
这个时候你只能:mHandler = new Handler(Looper.getMainLooper()). post (new Runnable()) {
//update UI
}