Viewmodel of Android Jetpack Series

Viewmodel of Android Jetpack Series Solution


foreword
In the previous two articles, we have learned about Lifecycle and DataBind. In this article, we will learn about the more important ViewModels in the Jetpack series. Many components of Jetpack are used together, so individual knowledge points may be somewhat " meaningless" but But it is the basis of our project actual combat!

Viewmodel of Android Jetpack Series.Use of ViewModel


ViewModel class is designed to store and manage interface-related data in a lifecycle-conscious manner. The ViewModel class allows data to survive configuration changes such as screen rotations. This sentence is easy to understand. Remember the example we gave when we explained Lifecycle. We still use that example. If you haven't seen it, you can move to:
Lifecycle of Android Jetpack series
Let's review the requirements again:
When the Activity is visible, we do a counting function, add 1 to the count every second, stop counting when the Activity is invisible, and set the count to 0 when the Activity is destroyed. When the count is no longer set to 0, the WorkUtil code is as follows:
public class WorkUtil implements LifecycleObserver {

private static final String TAG = "WorkUtil";
private boolean whetherToCount = true;
private int count = 0;
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
while (whetherToCount) {
try {
Thread.sleep(1000);
count++;
Log.d(TAG, "start: " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
@OnLifecycleEvent ( Lifecycle.Event.ON_STOP ) _
public void onStop ( ) {
whetherToCount = false;
Log.d (TAG, " onStop : ");
}
@OnLifecycleEvent ( Lifecycle.Event.ON_DESTROY ) _
public void onDestory ( ) {
}
}

We run the program to rotate the screen during the counting process, and the results are as follows:

We can see that when the screen is rotated, the data is destroyed due to the change in the life cycle, so the count of the counter starts from the initial value again, so how do we solve this problem, you will definitely say, cache , overriding the onSabeInstanceState () method, etc., all are possible but not elegant enough, so how to solve this problem elegantly, this is our protagonist ViewModel today .

Viewmodel of Android Jetpack Series.Use of ViewModel


Our new Main3ActivityModel inherits from ViewModel , and the count variable is defined in Main3ActivityModel as follows:
public class Main3ActivityViewModel extends ViewModel {
public int count = 0;
}

That's right, it's that simple, we can solve our above problem as long as we ensure that the variable counted is the variable in this model
We get ViewModel objects through ViewModelProviders
main3ActivityViewModel = ViewModelProviders.of (this ).get (Main3ActivityViewModel.class);

But this method is obsolete, the alternative is
main3ActivityViewModel = new ViewModelProvider (this ).get (Main3ActivityViewModel.class);

In order for WorkUtil to use the variables in the Model, we need to pass the ViewModel and add a new constructor in WorkUtil
private Main3ActivityViewModel main3ActivityViewModel ;
public WorkUtil ( Main3ActivityViewModel main3ActivityViewModel) {
this.main 3ActivityViewModel = main3ActivityViewModel;
}

We change the count variable count in WorkUtil to main3ActivityViewModel.count, as follows:
@OnLifecycleEvent ( Lifecycle.Event.ON_RESUME ) _
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
while (whetherToCount) {
try {
Thread.sleep(1000);
main3ActivityViewModel.count++;
Log.d(TAG, "start: " + main3ActivityViewModel.count);
} catch (InterruptedException e) {
e.printStackTrace ();
}
}
}
} ).start ();
}

In main3Activity, pass parameters in the lifecycle:
getLifecycle ( ) .addObserver (new WorkUtil (main3ActivityViewModel));

Run the program again, rotate the phone screen during operation, and print as follows:

ViewModel of Android Jetpack Series.We can see that after the screen is rotated, the count of the counter is preserved, so how does the viewModel do it, this is because the ViewModel object exists longer than the specific instance of the view or LifecycleOwners , the life cycle of the ViewModel As shown in the figure below (from the official website)

Viewmodel of Android Jetpack Series.Pass parameters to ViewModel
The current requirement for counting is to start from 0. We now modify the requirement as follows, using the number entered by the user as the starting point to start counting, so that the count in the ViewModel is not 0, but the incoming parameter, we define a variable in Main3Activity inputCount to simulate a number entered by the user
private int inputCount = 100;

Add a constructor in Main3ViewModel
public int count = 0;
public Main3 ActivityViewModel( int count) {
this.count = count;
}

Seeing this, you may say, can't we just pass a new one directly, please remember that this is absolutely impossible, because if we use direct instantiation to create a ViewModel , then the life cycle of the ViewModel is affected by the Activity . Affected, so why can we only get instances of ViewModel through ViewModelProvider .
We need to use ViewModelProvider.Factory to pass parameters. The new Main3ActivityViewModelFactor inherits from ViewModelProvider.Factory and rewrites its onCreate method, as shown below:
public class Main3ActivityViewModelFactory implements ViewModelProvider.Factory {
@NonNull _
@Override
public T create( @NonNull Class modelClass ) {
return null;
}
}

VideModel instance in create
private int count;
public Main3 ActivityViewModelFactory( int count) {
this.count = count;
}
@NonNull _
@Override
public T create( @NonNull Class modelClass ) {
return (T) new Main3ActivityViewModel(count);
}

When getting an instance in an Activity, the following method is used
main3ActivityViewModel = new ViewModelProvider ( this,new Main3ActivityViewModelFactory(inputCount)).get(Main3ActivityViewModel.class);

Run the program and print the result as follows:

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00