在调用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;
}