获取错误:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。
我真的不知道为什么。
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);
}
感谢您的帮助。
答案 0 :(得分:2)
您遇到此错误,因为您在另一个线程中操作视图而不是UI线程。
您的setText
方法会修改3个TextViews的文本(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);
}
答案 1 :(得分:1)
从字面上看,您试图从错误的线程设置视图中的字段。 OnClickListener创建一个新线程,但只有创建视图及其层次结构的线程可能会改变这些视图。
您可以重构使用http://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.html
或者,您可以将setter代码包装在runOnUiThread块中。这个网站上有一个例子,同时要注意为什么这可能不是一个好主意:Android: RunOnUiThread vs AsyncTask。
答案 2 :(得分:0)
你在一个线程上设置setText。将调用操作UI组件的方法放在runOnUiThread块中。