子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare()

在调用Toast(或者AlertDialog)的地方的前面加上Looper.prepare(),后边加上Looper.loop()即可解决问题;
也就是说用Looper.prepare()和Looper.loop()把Toast前后包起来
原因:Toast创建时需要创建一个Handler,但是这个Handler需要获得Looper的实例,而在子线程中是没有这个实例的,需要手动创建

Toast部分源码

public Toast(Context context) {
        mContext = context;
        mTN = new TN();
        mTN.mY = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.toast_y_offset);
    }

    private static class TN extends ITransientNotification.Stub {
        ……
        final Handler mHandler = new Handler();    
        ……
    }

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;
    }
    原文作者:奔跑的图腾
    原文地址: https://www.jianshu.com/p/89eea42701f2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞