如何循环setText() - 崩溃应用程序

时间:2018-04-14 08:15:35

标签: java android timer

我是Android编程的新手。现在,我想更新活动中的值并使用间隔更改它,并将其设置为我的活动中的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;
}
}

活动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()中设置文本,这导致应用程序关闭。谢谢。

1 个答案:

答案 0 :(得分:3)

是的,你的直觉是正确的。出现此问题是因为正在从计时器更新视图。

错误与此类似:

  

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

在Android中,视图只能从“UI线程”更新,也称为“主线程”。

这里的问题是Runnable的run()方法正在一个单独的线程中执行。

可以在主线程上从这样的活动中完成更新:

...
runOnUiThread(new Runnable() {
    @Override 
    public void run() {
        // Do all your view updates in here
        textView.setText("string");
    }
});
....

我无法看到您的代码的上下文,但如果它是一个片段: getActivity().runOnUiThread(...);

还有其他方法可以切换到主线程。您可能还想调查AsyncTask和Handlers。