1

当我想将 setText 设置为 textView 时,应用程序强制关闭并给我这个错误:

android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能接触其视图。

这是我的代码的一部分:

Thread ThreadRecording = new Thread(new Runnable() {
    public void run() {
        while(recorder)
        {
            if (body_num = 10)
            {
                TextView loog = (TextView)findViewById(R.id.textView1);
                loog.setText("Total : 10, Thank you");
            }
        }
    }
});
ThreadRecording.start();

有一个按钮;如果用户点击它,它会调用一个函数来设置body_num = body_num + 1,线程检查 body_num == 10

4

3 回答 3

3

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

因为只有使用 UI(主)线程,您才能操作视图。您可以使用 Hanlder 来更新您的视图。

Handler有两个主要用途:

  1. 安排消息和可运行文件在未来某个时间点执行;和
  2. 将要在与您自己的线程不同的线程上执行的操作排入队列。当为您的应用程序创建一个进程时,其主线程专用于运行一个消息队列,该队列负责管理顶级应用程序对象(活动、广播接收器等)以及它们创建的任何窗口。您可以创建自己的线程,并通过 Handler 与主应用程序线程进行通信。这是通过调用与以前相同的 post 或 sendMessage 方法来完成的,但来自您的新线程。给定的 Runnable 或 Message 将被安排在 Handler 的消息队列中,并在适当的时候进行处理。”
    ——来自“developer.android.com”

例子:

背景线:

new Thread() {

public void run() {
    while(recorder)
        {
            if (body_num = 10)
            {                
                messageHandler.sendEmptyMessage(0);
            }
        }
   }

}.start();

您放在主线程中的处理程序:

private Handler messageHandler = new Handler() {

public void handleMessage(Message msg) {
             //update your view here
   }
};
于 2012-12-27T01:01:22.163 回答
1

只能在UI线程中修改视图,需要用到Handler,比如,

Handler h = new Handler(context.getMainLooper()) {
    public void handleMessage(Message msg) {
        TextView loog = (TextView)findViewById(R.id.textView1);
        loog.setText(msg.obj);
    }
};

Thread ThreadRecording = new Thread(new Runnable() {
    public void run() {
        while(recorder)
        {
            if (body_num = 10)
            {
                Message message = new Message();
                message.obj = "Total : 10, Thank you";
                handler.sendMessage(message);
            }
        }
    }
});
ThreadRecording.start();
于 2012-12-27T00:57:34.293 回答
0

这也可以通过使用 AsyncTask 来实现。下面是在 TextView 中设置字符串资源 (R.string.your_text) 的示例代码:

public class CommonSetText extends AsyncTask<Void, Void, Integer> {
private WeakReference<TextView> textView;
private int stringID;

public CommonSetText ( TextView textView, Integer stringID) {
    this.textView = new WeakReference<>(textView);
    this.stringID = stringID;
}

@Override
protected Integer doInBackground ( Void... voids ) {
    return stringID;
}

@Override
protected void onPostExecute ( Integer stringID ) {
    super.onPostExecute ( stringID );
    textView.get ().setText ( stringID );
}
}

然后使用以下代码将文本设置为文本视图:

new CommonSetText ( textView, R.string.your_text ).execute (  );
于 2020-05-16T16:07:30.307 回答