androidandroid-lifecycleandroid-architecture-componentsandroid-architecture-lifecycle

LifeCycle Aware Codelab Concept


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.


Solution

  • 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.