I was learning the Lifecycle Aware Components from the Codelab which starts from Chronometer example. In step 2 I have a doubt. These are the code files for reference
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;
}
}
In the above code, we are calling the setTime() only once and only when the ViewModel is being created for the very first time, that is when you start the application after a complete close. And only setTime() method should update the Long variable mStartTime. and at the end of activity File, we are calling the start() method which should start the counting of the Chronometer.
Doubt:
If we are calling the set Method only once during the Life of the app and not Activity, how does the value of the Long variable mStartTime is being updated as we can see from the else part, were we are setting the base of the Chronometer as the variable. The value that the start() is returning is no way related to the variable, so how the setTime() function is being called again and again every second.
If we are calling the set Method only once during the Life of the app and not Activity
ViewModel
survive in configuration changes. ViewModel
depends on Activity not App Lifecycle. When your Activity destroyed (without Configuration changes) your ViewModel
will be also destroyed. For your case there is no guarantee that you are calling setStartTime
method only once in App Lifecycle.
how does the value of the Long variable mStartTime is being updated
Here if your ViewModel
is still alive then you are getting the previous basetime by chronometerViewModel.getStartTime()
by this method and setting chronometer base time.
how the setTime() function is being called again and again every second
Chronometer
automatically update display time in every second. You don't have to call setTime()
every second. Chronometer
take care of its update itself. You have to just set a base time where he should start.
Finally if your Activity destroyed for configuration changes your ViewModle
will still holds the previous data and you can use that so that you don't need recreate that data again.