bug: “Can't create handler inside thread that has not called Looper.prepare()”
1.问题描述
在Android Studio中运行项目时报异常: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
2.分析原因
Can't create handler inside thread that has not called Looper.prepare()
翻译过来的意思是:在子线程thread中不能创建handler,没有叫Looper.prepare()的方法。
分析:实际项目中是有创建了handler的,那为什么在子线程中还要创建handler呢?那最大的可能就是在子线程中有某些地方做了UI操作,并没有放到handler中去执行。所以运行时才会报错。记住一个原则,主线程不能做耗时操作,子线程中不能做更改UI操作,子线程需要通过handler才能来做更改UI的相关操作。
Note:若报这样的错误就去你的子线程中查找问题代码。一般开发工具都会提示哪里有错误的。细心点就ok了。
3.案例分析:
1)项目中报错如下:
04-21 10:16:52.930 17728-18371/com.******.debug E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-1385 Process: com.******.debug, PID: 17728 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.<init>(Handler.java:200) at android.os.Handler.<init>(Handler.java:114) at android.widget.Toast$TN.<init>(Toast.java:338) at android.widget.Toast.<init>(Toast.java:100) at android.widget.Toast.makeText(Toast.java:249) at com.******.app.base.PromptManager.showShortToast(PromptManager.java:173) at com.******.app.utils.APKVersionUpdate$3.run(APKVersionUpdate.java:193)
2)涉及报错的代码:
(注:只是为了说明问题,并没有贴出项目全部源码,所以只贴出了报错位置部分的代码)
new Thread() { @Override public void run() { try { //此处代码什么功能不重要, final File file = getFileFromServer(url, updateProgress); sleep(2000); installApk(file); if(updateProgress.isShowing()){ updateProgress.colseDialog(); } } catch (Exception e) { //我在此处做了更改UI的操作,才会报错 //这是自定义的吐司 PromptManager.showShortToast(TextActivity.this, "升级失败!请检查网络后重试"); //这是取消进度条对话框操作 if(updateProgress.isShowing()){ updateProgress.colseDialog(); } } } }.start();
3)更正后的代码:
在子线程中:
new Thread() { @Override public void run() { try { //此处代码什么功能不重要, final File file = getFileFromServer(url, updateProgress); sleep(2000); installApk(file); if(updateProgress.isShowing()){ updateProgress.colseDialog(); } } catch (Exception e) { handler.sendEmptyMessage(0); } } }.start();
在Handler中:
private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what){ case 0: //更新UI操作 PromptManager.showShortToast(MinxinApplication .getInstance().getApplicationContext(), "升级失败!请检查网络后重试"); if(updateProgress.isShowing()){ updateProgress.colseDialog(); } break; default:break; } }; };