An overview of the

ViewModel is still a category of Model, a vehicle for data objects, but with more binding to the View lifecycle. You can think of it simply as a data object with a life cycle. Can be used in activities and fragments to ensure that they are unique and consistent throughout their life cycle and are not subject to configuration changes (such as screen rotation).

Usage scenarios

  • A page screen rotation caused Activity/ Fragment destruction and reconstruction data cannot be saved. You might say I’m going to save it with onSaveInstanceState, and restore it with some onCreate, onRestoreInstanceState. OnSaveInstanceState is designed to store small UI-specific data that is not complex to serialize or deserialize. Serialization can consume a lot of memory if the object being serialized is complex. Since this happens during a configuration change in the main thread, it needs to be handled quickly so as not to lose frames and cause visual stuttering.
  • Still is the screen rotation problem, the general page reconstruction needs to request data again, if can cache down can reduce a request? Or you can leave it in the background for a while and come back and use onSaveInstance and it’s a little bit more cumbersome.
  • When an Activity+ Fragment is used, a single Fragment wants to take the Activity’s data and render it. This scenario is the same with Activity/ Fragment+ custom View. Fragment, Fragment, Fragment, Fragment, Fragment, Fragment, Fragment, Fragment, Fragment I would say you have to define the interface, is there a less cumbersome way to do it; In addition, if improperly called, the Activity is destroyed and a null pointer appears.
  • Imagine an Activity+ Fragment that needs to communicate with Fragments, or even if changes to one Fragment affect other Fragments. Your first instinct is to use an Activity as a mediator or to use Eventbus as a notification. Anyway, by learning about ViewModel, you’ll find a new way to solve these problems. It keeps the data unique throughout its life cycle without having to worry about null Pointers due to asynchronous operations.

ViewModel lifecycle

As you can see below, the ViewModel has the same or longer life cycle as an Activity/ Fragment, because if screen rotation occurs, the ViewModel is not destroyed until the final onDestroy.

The use of the ViewModel

1. Gradle dependency

dependencies {
    ...
    implementation 'android. Arch. Lifecycle: extensions: 1.1.1'
}
Copy the code

AndroidViewModel: getApplication(); AndroidViewModel: getApplication(); AndroidViewModel: getApplication()

public class CustomModel extends ViewModel { public CustomObj obj; // Business objects to be used}Copy the code

3. The use of the ViewModel

public class MyActivity extends Activity {
      public void myFunction() {// ViewModelProviders. Of (myactivity.this).get()"key", CustomModel.class); CustomModel customModel = ViewModelProviders.of(MyActivity.this).get(CustomModel.class); customModel.obj... // Operate on the object}}Copy the code

4.ViewModel is combined with LiveData

Public class CustomModel extends ViewModel {public MutableLiveData<string> Value = new MutableLiveData&lt; &gt; (a); }Copy the code
public class MyFragment1 extends Fragment {
      public void myFunction() { CustomModel customModel = ViewModelProviders.of(getActivity()).get(CustomModel.class); customModel.value.observe(MyFragment.this, New Observer<string>() {@override public void onChanged(string value) {textView.settext (value)}}); }}Copy the code
public class MyFragment2 extends Fragment {
      public void myFunction() {
              CustomModel customModel = ViewModelProviders.of(getActivity()).get(CustomModel.class);
              customModel.value.setValue("fragment2 changed the value"); // Note postValue}}Copy the code

In this way, the two fragments can communicate, and the introduction of LiveData can also monitor the changes of data reflected in the interface in real time. Now that you’ve mastered the basics of ViewModel, you can happily add Android Jetpack ViewModel to your resume. But if you don’t want to look blindsided and say, “I guess… Maybe… Probably… Is so, anyway as a love study of the siege division I was to see the source code.

ViewModel implementation principle

Guess how

1. Since you can store multiple viewModels, how are they stored? 2. Where is the ViewModel data stored? Application level or Activity/ Fragment level? 3. How to ensure that the ViewModel is not destroyed during configuration changes (such as screen rotation)? 4. How to ensure that Activity/ Fragment onDestroy is recovered? Viewmodel.class = viewModel.class = viewModel.class 6. Where is the Application held by AndroidViewModel set?

The principle of analysis

The implementation principle will be analyzed step by step below. If you are worried, please skip to the end and see the answer directly. Androidx conversion before and after the ViewModel storage method has changed, here we respectively talk about these two kinds of implementation:

Before androidx conversion

Blog.csdn.net/zhuzp_blog/…

  • ViewModel, AndroidViewModel is the class that we can inherit, which holds the Application object.
  • ViewModelStore is the class that stores viewModels, stored using HashMap.
  • ViewModelProviders Provides methods to obtain ViewModelProvider, including activity and Fragment
  • The ViewModelProvider combines VIewModelStore and Factory to get an example based on the name of the ViewModel. Factory has a default implementation and can be customized, and the first instance is created through Factory reflection.
  • HolderFragment is the key logic that implements the saving function of ViewModelStore. Essentially an empty Fragment inserted in an Activity/ Fragment that will not be destroyed if the configuration changes.
ViewModelProviders.of(activity/ fragment)



























ViewModelProvider.get(ViewModel.class)

















Androidx converted

1. Unchanged: ViewModel, AndroidViewModel, ViewModelStore, ViewModelProvider, Factory 2 Changed :ViewModelStores deprecated, HolderFragment removed. The Activity/ Fragment implements the ViewModelStoreOwner class, that is, the ViewModelStore exists in the Activity/ Fragment carrier itself. The difference in the source code is the way the ViewModelStore is obtained, as shown in Figure 13. In this implementation, the Activity/ Fragment stores the ViewModelStore in a different way than the HolderFragment does.

In the FragmentActivity ViewModelStore

The key point is onRetainNonConfigurationInstance (), getLastNonConfigurationInstance (), as for the principle to refer to.

















Fragments of ViewModelStore

Fragment implements the same retention mechanism, except that the data is stored in FragmentManagerNonConfig. Figure 18 shows the data that needs to be stored in the Activity when the configuration changes. The collection of fragments that are not destroyed (via setRetainInstance(True)), the data that needs to be saved in all the sub-fragments, and the ViewModelStore in all the fragments



















The principle of summary

The way the ViewModel is stored on Android and Android X is completely different, but the way it is exposed to use is the same, which shows the architecture’s care. At present, it coincides with the transition between Android and AndroidX. I am not sure which one will prevail. Questions 1, 5 and 6 above are implemented in the same way, and the answer is given here first: 1. Multiple ViewModels are stored in the ViewModelStore, which is essentially a Map store of key-value pairs. Key is the name of the ViewModel or the key you set when the GET method is used. 5. First check whether the ViewModelStore contains the instance. If yes, the instance is returned directly; if no, the instance is reflected and added to the ViewModelStore. 6.ViewModelProviders. Of (Activity /fragment). Unlike the ViewModel, it needs to pass the application.

  • Android support package: 2.ViewModel is essentially an Activity/ Fragment level. Use FragmentManager/ ChildFragmentManager to insert a fragment-HolderFragment without a View. The ViewModelStore is stored in the HolderFragment. 3. SetRetainInstance (true) on onCreate to ensure that the fragment is not destroyed when the screen rotates. 4.HolderFragment calls viewModelStore. clear while onDestroy and circulates viewModel.onCleared.
  • 2.ViewModel is still an Activity/ Fragment level, but the ViewModelStore is stored in FragmentActivity and Fragment respectively. The reconstruction process is the Activity destroyed by onRetainNonConfigurationInstance (), getLastNonConfigurationInstance () to save and restore ViewModelStore object; Fragment is slightly complex, Caching the FragmentManagerNonConfig object in saveNonConfig of saveAllState after onSaveInstanceState between FragmentActivity onStop and onDestroy The data stored in it includes the fragment collection that is not destroyed, the FragmentManagerNonConfig collection of looped child fragments, and the ViewModelStore collection of all fragments. They restore each Fragment’s ViewModelStore object when the FragmentActivity rebuilds onCreate. The ViewModelStore is normally destroyed. Only the ViewModelStore data is saved and restored in a particular scenario, both of which are actively triggered by FragmentActivity; 3. If the Activity/ Fragment onDestroy is caused by a configuration change, the ViewModelStore data is not cleared. Otherwise, the ViewModelStore data is cleared. In short, the uniqueness and integrity of the data in the current scope can be guaranteed no matter whether the storage medium of ViewModelStore is not destroyed or the data is saved and restored. The code is complex, but the design ideas are worth learning and digesting.

Pay attention to wechat public number, the latest technology dry goods real-time push