Can‘t create handler inside thread that has not called Looper.prepare()

Posted 阳光照不到的王国

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Can‘t create handler inside thread that has not called Looper.prepare()相关的知识,希望对你有一定的参考价值。

 

 

android开发过程中,如果在子线程中创建Handler时会出现下面这种异常。

Can't create handler inside thread that has not called Looper.prepare()

下面根据源码来解读下出现这个问题的原因

Handler所在的目录位置

/frameworks/base/core/java/android/os/Handler.java

1、Handler的构造函数

  public Handler() {
        //注释1
        this(null, false);
    }


    //注释2
    public Handler(Callback callback, boolean async) {
        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());
            }
        }
        //注释3
        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 = callback;
        mAsynchronous = async;
    }

注释1:在new Handler()时会调用注释2处的两个参数的构造函数。

下面观察注释3处,通过Looper.myLooper()来获取mLooper对象,如果mLooper对象为空则抛出此文章开头时出现的异常。

2、查看Looper.myLooper()函数做了什么。

Looper类对应Android源码目录如下

/frameworks/base/core/java/android/os/Looper.java

返回一个与当前线程关联的Looper对象,如果当前线程未关联Looper则返回null。

继续查看sTheadLocal。如果没有调用prepare()的话,sTheadLocal.get()将会返回null

看下prepare()函数

根据源码可以看出,调用prepare()函数之后才会调用sThreadLocal.set(Looper)。

走到这个步骤之后也就基本破案了,解决方法也一目了然。就是在子线程中创建Handler之前要调用一下Looper.prepare();

 

以上是关于Can‘t create handler inside thread that has not called Looper.prepare()的主要内容,如果未能解决你的问题,请参考以下文章

Can‘t create handler inside thread that has not called Looper.prepare()

在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()(示例代码

转 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()(示例

解决使用Handler时Can't create handler inside thread that has not called Looper.prepare()

Can't create handler inside thread that has not called Looper.prepare()

Android handler 报错处理Can't create handler inside thread that has not called Looper.prepare()(示例代码