首页 > 解决方案 > 当我第一次运行我的应用程序时,你不认为 runTimer() 方法会无限运行,因此永远不会调用 onStart() 方法吗?

问题描述

我的 OnStart() 方法不应被调用,因为我的 onCreate() 方法将无限运行。当 OnCreate 方法运行时,会调用 runTimer() 方法。这个runTimer方法会因为handler.postDelayed而无限运行。Android Studio 是如何完成 runTimer() 方法的无限循环然后调用 OnStart() 方法的?

    // MY STOPWATCH APP        
    


    public class MainActivity extends AppCompatActivity {
    private int seconds = 0;
    private boolean running;
    private boolean wasRunning;

    @Override
    // ON RUNNING MY APP FOR THE FIRST TIME THIS METHOD WILL GET CALLED FIRST.
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null) {
            seconds = savedInstanceState.getInt("seconds");
            running = savedInstanceState.getBoolean("running");
            wasRunning = savedInstanceState.getBoolean("wasRunning");
        }
        
        runTimer();
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt("seconds", seconds);
        savedInstanceState.putBoolean("running", running);
        savedInstanceState.putBoolean("wasRunning", wasRunning);
    }

    @Override
    protected void onStop() {
        super.onStop();
        wasRunning = running;
        running = false;
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (wasRunning) {
            running = true;
        }
    }

    //Start the stopwatch running when the Start button is clicked.
    public void onClickStart(View view) {
        running = true;
    }

    //Stop the stopwatch running when the Stop button is clicked.
    public void onClickStop(View view) {
        running = false;
    }

    //Reset the stopwatch when the Reset button is clicked.
    public void onClickReset(View view) {
        running = false;
        seconds = 0;
    }

    //Sets the number of seconds on the timer.
    private void runTimer() {
        final TextView timeView = (TextView)findViewById(R.id.tv_time_view);
        final Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                int hours = seconds/3600;
                int minutes = (seconds%3600)/60;
                int secs = seconds%60;
                String time = String.format(Locale.getDefault(),
                        "%d:%02d:%02d", hours, minutes, secs);
                timeView.setText(time);
                if (running) {
                    seconds++;
                }
                handler.postDelayed(this, 1000);
            }
        });
    }
}

标签: javaandroidandroid-studiorunnableandroid-handler

解决方案


为什么你认为它runTimer()会无限期地运行?

handler.post()并将handler.postDelayed()对象(您的new Runnable() {})添加到消息队列中,以便run()稍后可以执行对象方法。

handler.post()在将对象添加到消息队列后返回,因此runTimer()andonCreate()方法正常完成。


为什么是“消息队列”?因为文档是这样说的:

https://developer.android.com/reference/android/os/Handler

处理程序允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象

https://developer.android.com/reference/android/os/Handler#post(java.lang.Runnable)

使 Runnable r 添加到消息队列中。可运行对象将在附加此处理程序的线程上运行。

https://developer.android.com/reference/android/os/Handler#postDelayed(java.lang.Runnable,%20long)

使 Runnable r 添加到消息队列中,在经过指定的时间后运行。

使用 a 的全部意义Handler在于允许Runnable被编辑的 spost()在稍后的某个时间点执行,以便当前线程可以继续其工作。

如果处理程序将在直接(和阻塞)内执行代码,Runnable那么您可以将代码编写为new Runnable() { /*...*/ }.run();


推荐阅读