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


                    Looper.prepare();  // Can't create handler inside thread that has not called Looper.prepare()。
Toast.makeText(context,"登录超时",Toast.LENGTH_SHORT).show();
Looper.loop();

这样子写就不会报错了;

但是他为什么报错???你是不是在子线程显示Toast了;来看一下Toast的源码:

    /**
* Constructs an empty Toast object. If looper is null, Looper.myLooper() is used.
* @hide
*/
public Toast(@NonNull Context context, @Nullable Looper looper) {
mContext = context;
mTN = new TN(context.getPackageName(), looper);
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}

TN : 就看最主要这一点吧!

  if (looper == null) {
// Use Looper.myLooper() if looper is not specified.
looper = Looper.myLooper();
if (looper == null) {
throw new RuntimeException(
"Can't toast on a thread that has not called Looper.prepare()");
}
}
mHandler = new Handler(looper, null) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW: {
IBinder token = (IBinder) msg.obj;
handleShow(token);
break;
}
case HIDE: {
handleHide();
// Don't do this in handleHide() because it is also invoked by
// handleShow()
mNextView = null;
break;
}
case CANCEL: {
handleHide();
// Don't do this in handleHide() because it is also invoked by
// handleShow()
mNextView = null;
try {
getService().cancelToast(mPackageName, TN.this);
} catch (RemoteException e) {
}
break;
}
}
}
};

报错的原因是因为你的looper == null ,myLooper也是null;

Toast的内部会创建Handler,而Handler又依赖于Looper;Looper不存在,自然会报错;

Android主线程会默认创建Looper,而子线程则不会默认创建Looper;所以我们需要手动去创建Looper并开启循环;

上一篇:JSP入门 el表达式


下一篇:物联网的日益普及如何影响大学校园