异常:--------Only the original thread that created a view hierarchy can touch its views
?
cause by :?Can't create handler inside thread?
?
代码如下:
?
?
private OnClickListener btnLisener = new OnClickListener() { public void onClick(View arg0) { createProgressDialog(MainActivity.this); new ExcuteRunnable("today").start(); } }; class ExcuteRunnable extends Thread{ private String method; ExcuteRunnable(String method){ this.method = method; } @Override public void run() { try { dataProvider = requestData(method); setDataProvider(dataProvider);//更新UI的数据源 progressDialog.dismiss(); } catch (Exception e) { e.printStackTrace(); } } }
?
Activity是主线程 ?在一个新的线程里更新另一个线程的UI 报此异常,主要是Android的相关View和控件不是线程安全的
?
?
出现此异常解决方法有二,都是利用Handler类,即使新现成不能操作原始线程那就将更新的操作放到原始线程中
?
在原始线程中创建一个handler对像 ?重写handlMessage方法,在新线程中通过handler.sendMessage 激活刚方法
?
问题得到解决
?
?
private OnClickListener btnLisener = new OnClickListener() {
public void onClick(View arg0) { createProgressDialog(MainActivity.this); new ExcuteRunnable("today").start(); } };
?public Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if(progressDialog!=null)progressDialog.dismiss(); if(msg.what == 0)//成功 setDataProvider(dataProvider);//将setDataProvider 从 requestData()方法中分离 在新线程中无法操作主线程的UI else popMsg("错误", "请求数据出错!", MainActivity.this); } }; /** * 启动一个线程请求数据 * @author liucf */ class ExcuteRunnable extends Thread{ private String method; ExcuteRunnable(String method){ this.method = method; } @Override public void run() { try { dataProvider = requestData(method); handler.sendEmptyMessage(0); } catch (Exception e) { handler.sendEmptyMessage(1); } } }
??二,原始线程中创建handler对像 将新线程加入到handler消息队列中
?
final Handler handler= new Handler(); final Runnable runaable = new Runnable() { public void run() { setDataProvider(requestData("today")); } };?private OnClickListener btnLisener = new OnClickListener() { public void onClick(View arg0) { createProgressDialog(MainActivity.this); requestData(); } };protected void requestData() { Thread t = new Thread() { public void run() { handler.post(runnable); //加入到消息队列 这样没有启动新的线程,虽然没有报异常。但仍然阻塞ProgressDialog的显示 } }; t.start(); }
?