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(""); } });