子线程创建Handler
这篇是看郭霖大神博客写的
相当于读书笔记而已
博客地址是:http://blog.csdn.net/guolin_blog/article/details/9991569
一.子线程中不能创建Handler
new Thread(new Runnable() {
@Override
public void run() {
Handler handler = new Handler();
}
}).start();
这样会报错:
Can't create handler inside thread that has not called Looper.prepare()
二.创建之前增加Looper.prepare();
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler handler = new Handler();
}
}).start();
三.为什么要增加Looper.prepare();
看看源码
看看Handler的构造函数
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
我们看到先是mLooper = Looper.myLooper();
然后判断如果mLooper为空,就报这个错误
四.为什么会出现mLooper的情况
看看myLooper()这个方法
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
这个方法的意思就是:从sThreadLocal中取出一个Looper
mLooper为空,就说明sThreadLocal里面没有Looper
五.为什么sThreadLocal里面没有Looper
我们来看看Looper的prepare()方法就完全明白了
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
调用prepare方法的时候也是先调用sThreadLocal的get方法
检查一下现在sThreadLocal里面有没有Looper
如果sThreadLocal不为空,那么就报错:一个线程只能有一个Looper
如果sThreadLocal里面还没有Looper,那么就给sThreadLocal设置一个new Looper()
六.为什么主线程不需要prepare
因为程序启动的时候,系统已经自动调用了主线程的Looper.prepare()方法
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
里面Looper.prepareMainLooper()就是
七.总结:
主线程已经自动prepare过了,子线程中创建Handler需要prepare.