今天在另外的一个工作线程中调用一个API,主要是想要弹出一个对话框,结果出现错误:Only the original thread that created a view
hierarchy can touch its views!处理方法如下。
首先我们需要明白,主线程或者这里说的原始线程original thread
一般情况下是UI线程,当然UI线程并不一定是主线程,我们不能长时间的阻塞该应用,在Android平台上可能会产生类似Force close或Wait这样的对话框这里我们成为ANR,这里除了使用ProgressDialog方式给用一个动态的进度代表当前处理并没有中断可能需要一些时间,相关的网络处理可以使用工作线程,但是worker 线程不能处理显示元素即UI相关的View或Widget包中的高层的控件,所以通过一个Handler对象可以很好的传递Runnable或Message 。
我想在线程中调用的api如下
:
private void
doNeedExit() {
//弹出对话框时,隐藏进度条
myProgressBar.setVisibility(4); // INVISIBLE
StringBuffer sb = new StringBuffer();
sb.append("频道不能播放!");
Dialog dialog = new
AlertDialog.Builder(PlayerActivity.this)
.setCancelable(false) //设置不响应回退(return)
.setTitle("提示")
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(sb.toString())
//
设置内容
.setPositiveButton("退出",//
设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
PlayerActivity.this.finish();
}
}).create();//
创建
//
显示对话框
dialog.show();
}
如果在工作线程里调用doNeedExit()
如下: (红色部分)
Thread PlayThread = new
Thread(){
public void run() {
System.out.printf("[PlayerActivity] PlayThread Run\n");
if(PlayUrl != null)
{
System.out.printf("[PlayerActivity] PlayUrl = [%s] \n"
,PlayUrl);
try
{
//设置需要播放的视频
mediaPlayer.reset();
mediaPlayer.setDataSource(PlayUrl);
//把视频画面输出到SurfaceView
mediaPlayer.setDisplay(surfaceView.getHolder());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
doNeedExit();
}
}
};
则会出现错误:
Only the original thread that created a view
hierarchy can touch its views
处理方法如下:
//定义
UI handle runnable
Handler myUIHandler = new Handler();
Runnable mUpdateUI = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
UpdateUI();
}
};
//
实现UpdateUI
API
private void UpdateUI()
{
//需要更新的UI
System.out.printf("[UpdateUI] Run \n");
doNeedExit();
}
最终在工作线程里如下调用:
//doNeedExit();
myUIHandler.post (mUpdateUI);
错误就不会再出现了!
加载中,请稍候......