1、错误提示: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:324)
2、简单说明以下问题,当我们需要在线程里面下载文件或图片时,有时候可能会连接不上网络,或找不到资源,有可能出现异常的问题,这个时候我们需要用一个 Toast 提示我们下载失败,按照常规,我们会在网络下载的地方处理异常捕捉,在 catch 里面使用 Toast ,这个做法是错误的。
看一下代码吧!
启动线程的代码:
final ProgressDialog dialog = ProgressDialog.show(WelcomeActivity.this,
"更新文件", "图片下载中,请稍候……");
new Thread(new Runnable() {
public void run() {
if (isNetworkAvailable()) {
try {
goImage(); // 调用下载图片的方法
Thread.sleep(1000);
} catch (Exception e) {
dialog.dismiss(); // 捕捉到异常后,把进度条销毁
Toast.makeText(WelcomeActivity.this, "你下载图片失败", 0).show();
goMainAty(); // 跳转到主界面
return; //这里注意:当服务器出现故障的时候,就要跳出run()里面的方法,否则会出致命的错误
}
} else {
Toast.makeText(WelcomeActivity.this, "网络链接出错,请检查网络!", 1) .show();
Log.d("Thread","isNetworkAvailable() error!");
}
dialog.dismiss();
goMainAty(); // 跳转到主界面
}
}).start(); // 启动线程
private void goImage() throws Exception {
MyDB db = new MyDB(WelcomeActivity.this); // 获取自定义的数据库连接类
Cursor cursor = db.SECELTSQL(InfoBean.find()); // 执行查询语句,得到 Cursor 集合对象
String[] list = getList(cursor); // 把cursor集合里的所有元素加到 String[]类型数组中
if (list.length != 0) {
ThreadLoadImage(list); // 调用线程下载图片的方法
}else{
Log.d("WecomeActivity", "下图片的list.size()为空!");
}
}
再看下载图片的方法:
/**
* @param list 传入的是一个 String 类型的数组
* @throws Exception
*/
private void ThreadLoadImage(final String[] list) throws Exception {
for(int i=0;i<list.length;i++){
LoadBitmap load = new LoadBitmap(WelcomeActivity.this);
Bitmap bitmap = load.getBitmap(list[i],String.valueOf(i+1));
Log.d("WelcomeActivity.java", "LoadBitmap(WelcomeActivity.this) is OK!");
}
}
从上面的代码似乎没出现什么问题,但是在运行的时候,要是遇到下载图片的异常的时候就出现问题了,但是测试的时候,我故意把服务器关了,问题就来了

错误是 Toast 在Handler 里面初始化的时候出错,
从这个错误中,我得出一点,就是在线程里,不能在执行UI上的东西,典型的就是我的这个错误,不能显示 Toast , 在很多教材或网上也提到,在线程下载完成不能这里面执行线程 ,解决的方法,是用 Handler 实现UI 的显示;
Handler mhandler = new Handler(){
public void handleMessage(Message msg){
if(msg.what == 0x100){
Toast.makeText(WelcomeActivity.this, "你下载图片失败", 0).show();
}
}
};
在线程里要如下更改:
final ProgressDialog dialog = ProgressDialog.show(WelcomeActivity.this,
"更新文件", "图片下载中,请稍候……");
new Thread(new Runnable() {
public void run() {
if (isNetworkAvailable()) {
try {
goImage(); // 调用下载图片的方法
Thread.sleep(1000);
} catch (Exception e) {
dialog.dismiss(); // 捕捉到异常后,把进度条销毁
// Toast.makeText(WelcomeActivity.this, "你下载图片失败", 0).show();
Message m = new Message();
m.what =0x100;
mhandler.sendMessage(m);
goMainAty(); // 跳转到主界面
return; //这里注意:当服务器出现故障的时候,就要跳出run()里面的方法,否则会出致命的错误
}
} else {
Toast.makeText(WelcomeActivity.this, "网络链接出错,请检查网络!", 1) .show();
Log.d("Thread","isNetworkAvailable() error!");
}
dialog.dismiss();
goMainAty(); // 跳转到主界面
}
}).start(); // 启动线程
private void goImage() throws Exception {
MyDB db = new MyDB(WelcomeActivity.this); // 获取自定义的数据库连接类
Cursor cursor = db.SECELTSQL(InfoBean.find()); // 执行查询语句,得到 Cursor 集合对象
String[] list = getList(cursor); // 把cursor集合里的所有元素加到 String[]类型数组中
if (list.length != 0) {
ThreadLoadImage(list); // 调用线程下载图片的方法
}else{
Log.d("WecomeActivity", "下图片的list.size()为空!");
}
}