我是 Android 编程新手。现在,我想以指定的时间间隔更新 Activity
中的 TextView
值。
汽车类:
public class Car {
public int Speed;
public int RPM;
public int Distance;
public int Fuel;
public Car(int Speed, int RPM, int Distance, int Fuel) {
System.out.println(
"Inisialisasi Baru"+
"\nSpeed: "+ Speed +
"\nRPM: "+ RPM +
"\nDistance: "+ Distance +
"\nFuel: "+ Fuel
);
this.Speed = Speed;
this.RPM = RPM;
this.Distance = Distance;
this.Fuel = Fuel;
}
public int getSpeed() {
return Speed;
}
public int getRPM() {
return RPM;
}
public int getDistance() {
return Distance;
}
public int getFuel() {
return Fuel;
}
}
Activity java:
TextView carSpeed, carRPM, carDistance, carFuel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mock);
carSpeed = (TextView) findViewById(R.id.carSpeed);
carRPM = (TextView) findViewById(R.id.carRPM);
carDistance = (TextView) findViewById(R.id.carDistance);
carFuel = (TextView) findViewById(R.id.carFuel);
new Timer().scheduleAtFixedRate(new TimerTask(){
Car car = new Car(20, 20, 20, 5);
@Override
public void run(){
int maxSpeed = car.Speed + 5;
int minSpeed = car.Speed - 4;
int maxRPM = car.RPM + 5;
int minRPM = car.RPM - 4;
car.Speed = new Random().nextInt((maxSpeed - minSpeed) + 1) + minSpeed;
car.RPM = new Random().nextInt((maxRPM - minRPM) + 1) + minRPM;
car.Distance += 1;
car.Fuel -= 1;
if (car.Fuel <= 0) {
car.Fuel += 20;
}
if (car.Speed <= 0) {
car.Speed = 20;
} else if (car.Speed >= 150) {
car.Speed -= 50;
}
carSpeed.setText(Integer.toString(car.getSpeed()) + " km/h");
carRPM.setText(Integer.toString(car.getRPM()) + " rpm");
carDistance.setText(Integer.toString(car.getDistance()) + " km");
carFuel.setText(Integer.toString(car.getFuel()) + " l");
}
},0,5000);
}
我认为问题的发生是因为我试图在新的 Timer()
中 setText
并且这导致应用程序关闭。谢谢。
最佳答案
是的,您的直觉是正确的。出现问题是因为 View 正在从计时器更新。
错误将类似于:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
在 Android 中, View 只能从“UI 线程”(通常称为“主线程”)进行更新。
这里的问题是Runnable的run()方法是在一个单独的线程中执行的。
更新可以在 Activity 的主线程上完成,如下所示:
...
runOnUiThread(new Runnable() {
@Override
public void run() {
// Do all your view updates in here
textView.setText("string");
}
});
....
我看不到你代码的上下文,但如果它是一个 fragment :
getActivity().runOnUiThread(...);
切换到主线程还有其他方法。您可能还想研究 AsyncTask 和 Handlers。
关于java - 带有 scheduleAtFixedRate 的 Timer 和 TimerTask 在更新 TextView 时导致 CalledFromWrongThreadException 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49829326/