setText出错:“只有原始线程..才能触及其视图”

时间:2012-12-27 00:47:32

标签: android

当我想将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

3 个答案:

答案 0 :(得分:3)

  

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

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

Handler有两个主要用途:

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

    Backgroud主题:

    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
       }
    };
    

答案 1 :(得分: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();

答案 2 :(得分: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 (  );