Android CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触视图

Android CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触视图,android,handler,android-asynctask,Android,Handler,Android Asynctask,我对Android中的以下错误有疑问: CalledFromErrorThreadException;:只有 创建新线程的原始线程 视图层次可以触及其视图 当我尝试在我的活动中更新Textview时,似乎会发生这种情况,更新Textview的调用是从我的活动中发出的,但我仍然收到上述错误 我是这样的: Message stringMessage = Message.obtain(myTextHandler); stringMessage.obj = "Hello!"; stringMessage

我对Android中的以下错误有疑问:

CalledFromErrorThreadException;:只有 创建新线程的原始线程 视图层次可以触及其视图

当我尝试在我的活动中更新Textview时,似乎会发生这种情况,更新Textview的调用是从我的活动中发出的,但我仍然收到上述错误

我是这样的:

Message stringMessage = Message.obtain(myTextHandler);
stringMessage.obj = "Hello!";
stringMessage.sendToTarget();
onCreate() -设置按钮和文本视图

onStateChange()-一个侦听器,用于接收有关状态更改的通知,如果更改TextView以显示一些不同的文本,则会收到通知

当我收到新文本的通知时,我尝试更改文本视图,如下所示:

((TextView)findViewById(R.id.title)).setText("Some Text");
但是我得到了上面的错误

通过谷歌搜索,我似乎应该使用处理程序来更改TextView,或者使用AsyncTask

有人能解释一下哪一个更好用,为什么

编辑:添加代码段:





看来你找错方向了。尝试使用处理程序在正确的线程上更新GUI。参见android.com上的示例。基本上,您可以将
byeSetup
包装在
Runnable
中,并使用
处理程序
实例调用它

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

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

扩展willcodejavaforfood对清晰性和实施的回答

我让这项工作,下面是我如何做到的。我在一个服务中运行多个处理线程,所以在活动中运行的其他解决方案不起作用,例如runOnUiThread(newrunnable(){}

将其放在服务类的顶部,以便在该类的任何地方都可以访问:

Handler handler;
将其放入服务类onCreate方法或加载到服务主线程上的内容中

handler= new Handler(Looper.getMainLooper());
将其放入附加线程中,以“回发”代码,以便在UI或服务UI中运行(无论其名称如何):


另一种方法,这次使用的是
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();

当更改涉及到主线程(UiThread)时,请在另一个线程内使用它来更改任何视图

runOnUiThread(new Runnable() {
    @Override
    public void run() {

      // TODO your Code 
        et_Pass.setText("");
    }
});

您可以使用view的内置post方法更新其他线程中的内容,就像我在kotlin中使用编辑文本一样

address_box.post { address_box.text="my text"}

您是否在子类中?onStateChange在何处被重写?Hi Pentium10,它通过AIDL接口被重写,并与服务通信,服务将收到某些更改的通知,然后通知活动基于此更新其TextView。我添加了代码段以更好地演示我正在尝试的内容,错误似乎是错误非常随机地出现,当活动在前台时出现,而不是。可能的重复看起来我不必杀了我。PhewI认为Keshav的答案更好。这比使用
runOnUiThread()更好吗
?我可以看出,我们不需要对活动的引用。此解决方案还有其他优点吗?这应该是可以接受的答案,如果您使用的是Fragment,可以通过getActivity.runOnUiThread()调用此方法。。。。。。
Message stringMessage = Message.obtain(myTextHandler);
stringMessage.obj = "Hello!";
stringMessage.sendToTarget();
runOnUiThread(new Runnable() {
    @Override
    public void run() {

      // TODO your Code 
        et_Pass.setText("");
    }
});
address_box.post { address_box.text="my text"}