记录一次因为Android版本不同导致的crash异常:Can't create handler inside thread that has not called Looper.prepare()

来源:互联网 发布:ubuntu wiki 编辑:程序博客网 时间:2024/06/07 07:00

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。


0 0
原创粉丝点击