0

我正在从 Chronometer 示例开始的 Codelab 中学习 Lifecycle Aware Components。在第 2 步中,我有疑问。这些是供参考的代码文件

ChronoActivity2.java

package com.example.android.lifecycles.step2;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.widget.Chronometer;
import com.example.android.codelabs.lifecycle.R;

public class ChronoActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // The ViewModelStore provides a new ViewModel or one previously created.
        ChronometerViewModel chronometerViewModel
                = ViewModelProviders.of(this).get(ChronometerViewModel.class);

        // Get the chronometer reference
        Chronometer chronometer = findViewById(R.id.chronometer);

        if (chronometerViewModel.getStartTime() == null) {
            // If the start date is not defined, it's a new ViewModel so set it.
            long startTime = SystemClock.elapsedRealtime();
            chronometerViewModel.setStartTime(startTime);
            chronometer.setBase(startTime);
        } else {
            // Otherwise the ViewModel has been retained, set the chronometer's base to the original
            // starting time.
            chronometer.setBase(chronometerViewModel.getStartTime());
        }

        chronometer.start();
    }
}

ChronometerViewModel.java

package com.example.android.lifecycles.step2;
import android.support.annotation.Nullable;
import android.arch.lifecycle.ViewModel;

/**
 * A ViewModel used for the {@link ChronoActivity2}.
 */
public class ChronometerViewModel extends ViewModel {

    @Nullable
    private Long mStartTime;

    @Nullable
    public Long getStartTime() {
        return mStartTime;
    }

    public void setStartTime(final long startTime) {
        this.mStartTime = startTime;
    }
}

在上面的代码中,我们只在第一次创建 ViewModel 时调用setTime() ,即在完全关闭后启动应用程序时。只有setTime()方法应该更新 Long 变量mStartTime。在活动文件结束时,我们调用start()方法,该方法应该开始计时码表的计数。

怀疑:

如果我们在应用程序的生命周期而不是 Activity 期间只调用一次 set 方法,从else部分可以看出,Long 变量 mStartTime 的值是如何更新的,我们是否将 Chronometer 的基础设置为变量。start()返回的值与变量没有任何关系,因此setTime()函数如何每秒一次又一次地被调用。

4

2 回答 2

0

您对持久性的疑问在这里得到解答!

检查此官方代码实验室链接,并在第 2 步中阅读页面底部的内容

- 视图模型仅链接到活动/片段生命周期!- 这并不意味着长期坚持

您对 <code>SystemClock.elapsedRealtime()</code> 是否被一次又一次调用的疑问在这里得到解答

  • 基准时间只是计时器必须从中计数的参考,需要设置一次
  • SystemClock.elapsedRealtime()必须调用一次,当您调用时,计时器会处理从该基准时间开始计数start()

希望这可以消除您的疑虑,您可以在此处查看官方谷歌文档以检查计时器的工作原理。

于 2018-07-08T04:15:45.523 回答
0

如果我们在应用程序的生命周期中只调用一次 set 方法而不是 Activity

ViewModel在配置更改中生存。ViewModel取决于活动而不是应用程序生命周期。当您的 Activity 被销毁(没有配置更改)时,您ViewModel也将被销毁。对于您的情况,不能保证您setStartTime在 App Lifecycle 中只调用一次方法。

Long 变量 mStartTime 的值是如何更新的

在这里,如果您ViewModel还活着,那么您将chronometerViewModel.getStartTime()通过此方法获取上一个基准时间并设置计时器基准时间。

如何每秒一次又一次地调用 setTime() 函数

Chronometer每秒自动更新显示时间。您不必setTime()每秒钟都打电话。Chronometer照顾它的更新本身。您只需设置他应该开始的基本时间。

最后,如果您的 Activity 因配置更改而销毁,您ViewModle仍将保留以前的数据,您可以使用它,这样您就不需要再次重新创建该数据。

于 2018-07-08T03:25:48.820 回答