CalledFromWrongThreadException:只有创build视图层次结构的原始线程才能触及视图

我在Android中遇到以下错误:

CalledFromWrongThreadException;:只有创build视图层次结构的原始线程可以触及其视图

当我尝试在我的Activity中更新Textview时,似乎发生了这种情况,更新TextView的调用是在我的Activity中发生的,但仍然出现上述错误。

我有这样的:

onCreate() – 设置button和文本视图。

onStateChange() – 一个关于状态改变的通知的监听器,当这个监听器得到通知时,如果改变TextView来说一些不同的文本。

当我得到一个新的文本的通知我尝试更改TextView,如下所示:

((TextView)findViewById(R.id.title)).setText("Some Text"); 

但是我得到上面的错误。

从谷歌search它,看来我应该使用处理程序来更改TextView或可能使用AsyncTask?

任何人都可以解释哪一个会更好用,为什么?

编辑:添加代码片段:


  public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.my); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title); ((TextView)findViewById(R.id.time)).setText("Hello Text"); findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:")); startActivity(dialIntent); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); } }); } 

 //CallBacks from running Service private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){ @Override public void onStateChanged(int callState) throws RemoteException { switch(callState){ case GlobalData.CALL_STATUS_IDLE: break; case GlobalData.CALL_STATUS_DISCONNECTING: byeSetup(); break; } }; 

 public void byeSetup(){ ((TextView)findViewById(R.id.time)).setText("Bye Text"); findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { //Void the Button }}); } 

看起来你是在错误的线程。 尝试使用处理程序更新右侧线程上的GUI。 请参阅从android.com 的UI线程示例处理昂贵的操作 。 基本上你会将byeSetup包装在一个Runnable ,并用Handler实例调用它。

 Handler refresh = new Handler(Looper.getMainLooper()); refresh.post(new Runnable() { public void run() { byeSetup(); } }); 

对于其他人,只需要replacebyeSetup(); 用你的代码语句或方法。 byeSetup()是一个示例方法。 希望能节省一些时间。

扩大在willcodejavaforfood的答案澄清和实施…

我得到这个工作,下面是我如何做到这一点。 我在一个服务中运行多个处理线程,所以其他在Activity中运行的解决scheme不起作用,比如runOnUiThread(new Runnable(){} …

把它放在你的服务类的顶部,这样它就可以在这个类的任何地方访问:

 Handler handler; 

把这个放在你的service类的onCreate方法或者在Service主线程上加载的东西

 handler= new Handler(Looper.getMainLooper()); 

把它放在你的附加线程中,以“回传”代码来运行在UI或服务UI中(被称为):

 handler.post(new Runnable() { public void run() { playNext(); //or whatever method you want to call thats currently not working } }); 

另一种方法,这次使用android.os.Message

android.os.Handler定义为您的活动中的一个字段:

 private final Handler myTextHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message stringMessage) { textView.append((String) stringMessage.obj); return true; } }); 

然后从这样的其他线程喂它:

 Message stringMessage = Message.obtain(myTextHandler); stringMessage.obj = "Hello!"; stringMessage.sendToTarget(); 
  runOnUiThread(new Runnable() { @Override public void run() { // TODO your Code et_Pass.setText(""); } });