Android错误:只有创建视图层次结构的原始线程才能接触其视图
获取错误:android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。Android错误:只有创建视图层次结构的原始线程才能接触其视图,android,multithreading,text,Android,Multithreading,Text,获取错误:android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。 我真的不知道为什么 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button gen
我真的不知道为什么
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generate = (Button) findViewById(R.id.gen);
final TextView dice1 = (TextView) findViewById(R.id.dice1);
final TextView dice2 = (TextView) findViewById(R.id.dice2);
final TextView dice3 = (TextView) findViewById(R.id.dice3);
generate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dice1.setText(" ");
dice2.setText(" ");
dice3.setText(" ");
Thread thread = new Thread()
{
@Override
public void run() {
try {
while(true) {
sleep(2000);
setText("lol", "lol", "lol");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
});
}
public void setText(String d1, String d2, String d3){
dice1.setText(d1);
dice2.setText(d2);
dice3.setText(d3);
}
谢谢您的帮助。您正在将setText设置为一个独立的线程。将调用操作UI组件的方法放在runOnUiThread块中。实际上,您试图从错误的线程在视图上设置字段。OnClickListener会创建一个新线程,但只有创建视图及其层次结构的线程才能更改这些视图 您可以重构以使用
或者,您可以将setter代码包装到runOnUiThread块中。这个网站上有一个例子,同时也有一个警告,说明为什么这可能不是一个好主意:。您有这个错误,因为您在UI线程之外的另一个线程中操作视图。 您的
setText
方法修改3个文本视图的文本(dice1
,dice2
,dice3
)
您应该使用runOnUiThread
调用此方法,如下所示:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generate = (Button) findViewById(R.id.gen);
final TextView dice1 = (TextView) findViewById(R.id.dice1);
final TextView dice2 = (TextView) findViewById(R.id.dice2);
final TextView dice3 = (TextView) findViewById(R.id.dice3);
generate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dice1.setText(" ");
dice2.setText(" ");
dice3.setText(" ");
Thread thread = new Thread()
{
@Override
public void run() {
try {
while(true) {
sleep(2000);
runOnUiThread(new Runnable() {
@Override
public void run() {
setText("lol", "lol", "lol");
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
});
}
public void setText(String d1, String d2, String d3){
dice1.setText(d1);
dice2.setText(d2);
dice3.setText(d3);
}
睡在一根线里是个糟糕的设计@Raghundan如果在主线程上调用sleep(),则是,但在本例中不是。但是,可以肯定的是,使用一个示例可能比用户每次单击“生成”按钮时创建一个线程要好……如果您实现
线程或HandlerThread
,请确保您的UI线程在等待工作线程完成时不会阻塞-不要调用Thread.wait()或Thread.sleep()
。引用doc.Yes,它的意思是“不要在UI线程上调用Thread.wait(),等待另一个线程调用Thread.notify()。例如,在UI线程之外的另一个线程上调用Thread.sleep()(或Thread.wait())不会导致ANR。它会阻塞工作线程。因此这不好。我不是说它会导致ANR。