Can't create handler inside thread that has not called Looper.prepare()
该异常表示不能在非UI线程里面创建handler对象,通常是因为在工作线程中处理UI相关的操作或者在非UI线程中new新的Handler导致
一个APP上报crash日志,异常如下:
java.lang.RuntimeException:Can't create handler inside thread that has not called Looper.prepare()
| |
5 android.os.Handler.<init>(Handler.java:121)
| |
6 android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
| |
7 android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
| |
8 android.os.AsyncTask.<clinit>(AsyncTask.java:190)
|
经过百度,提示“
该异常表示不能在非UI线程里面创建handler对象,通常是因为在工作线程中处理UI相关的操作或者在非UI线程中new新的Handler导致”
但是这个问题只在Android的4.0.x和4.1.x系统中发现。查看工程代码,发现使用了asyncTask.
查看其Android 4.0的SDK源码,如下:
private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } }
在4.4的源码中,代码如下:
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); }
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }
发现出问题了,在asynctask的4.0的源码中没有InternalHandler的构造方法,所以会使用默认的Looper,之后谷歌修改了这地方代码,在构造方法中获取了Looper.getMainLooper。所以这个异常在老版本Android系统中才有问题。
总结:使用asyncTask时,最好在主线程中使用,否则在Android4.0和4.1的系统中会出现crash。