【Android】报错:Can't create handler inside thread that has not called Looper.prepare()
Toast.makeText(mContext, "msg", Toast.LENGTH_SHORT).show();
在子线程里创建 Toast
时出现报错:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare().
在没有调用Looper.prepare()
的线程里,无法创建handler
。
原因是修改 UI 需要在主线程里。
1. Thread
因为线程需要 Looper
来循环处理消息,但是子线程中默认是没有 Looper
的,查看一下 Looper
的源码,类注释如下:
/** * Class used to run a message loop for a thread. Threads by default do * not have a message loop associated with them; to create one, call * {@link #prepare} in the thread that is to run the loop, and then * {@link #loop} to have it process messages until the loop is stopped. * * Most interaction with a message loop is through the * {@link Handler} class. * *
This is a typical example of the implementation of a Looper thread, * using the separation of {@link #prepare} and {@link #loop} to create an * initial Handler to communicate with the Looper. * *
* class LooperThread extends Thread { * public Handler mHandler; * * public void run() { * Looper.prepare(); * * mHandler = new Handler() { * public void handleMessage(Message msg) { * // process incoming messages here * } * }; * * Looper.loop(); * } * }
*/
注释里说明了线程默认是没有 Looper
的,需要在线程里手动调用 Looper.prepare()
来创建 Looper
,并且调用 Looper.loop()
来遍历消息。并且还附带了一个例子。
所以我们直接按照官方给的例子调用即可:
new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "msg", Toast.LENGTH_SHORT).show(); Looper.loop(); }}).start();
2. Handler
如果直接在子线程里创建 new Handler()
,也会报同样的错误,因为子线程默认是没有 Looper 的。
可以使用 public Handler(Looper looper)
构造方法创建 Handler
,传递主线程的 Looper
:
new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Toast.makeText(mContext, "msg", Toast.LENGTH_SHORT).show(); }});
3. runOnUiThread
如果是在 Activity
里,可以使用 runOnUiThread
:
runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(mContext, "msg", Toast.LENGTH_SHORT).show(); }});
或者
if (mContext instanceof Activity) { ((Activity) mContext).runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(mContext, "msg", Toast.LENGTH_SHORT).show(); } });
参考
- Can’t create handler inside thread that has not called Looper.prepare()
- Android 子线程创建handler
- Android 带你彻底理解跨线程通信之Handler机制
更多相关文章
- 基于TCP和多线程实现无线鼠标键盘-Socket(2)
- ue4 创建Android和ios ar应用
- android 中文 api (71) —— BluetoothServerSocket[蓝牙]
- Android中有关Handler的使用(三)
- TTS源码解析
- android平台上的文件下载,文件和文件的操作
- Android(安卓)Studio中与网站通信
- Android的onCreateOptionsMenu()创建菜单Menu详解
- Android异步加载图片,并缓存到SD卡