Android JetPack~ ViewModel (1) Introduction and use

ViewModel, a part of the MVVM framework, its main function is to process business logic, data distribution, etc. It is a bridge connecting Mode and View. Compared with MVP, it is similar to P.

The ViewModel class has the following advantages:

  1. The ViewModel class is life-aware and has the same life cycle as the Activity bound to it. It can solve unnecessary troubles caused by the sudden destruction of the Activity when requesting the network.
  2. The data will not be lost if the device information changes (cut between horizontal and vertical screens). In fact, it only has one life cycle, which is triggered when the page is detected to be destroyed.
  3. Another feature of ViewModel is that you can use ViewModel to share data between Fragments of the same Activity.
  4. The ViewModel bound to each Activity is independent (between Activities)

img

1. Start using

Add dependencies

以前是需要添加依赖的,现在
方式一: implementation 'androidx.appcompat:appcompat:1.2.0',//这里面也包含ViewModel,LiveData等,
    
方式二: 也可以单独添加
implementation "androidx.fragment:fragment:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"

2、Activity

2.1, Create a new ViewModel

public class MyViewModel extends ViewModel {
    
    

    @Override
    protected void onCleared() {
    
    
        super.onCleared();
    }
}

The onCleared method is unique to ViewModel. It will be called when the Activity actually exits, not after it is destroyed, because onDestroy will also be called when the screen is rotated. So we can cancel network requests etc here. When you do not do any operations during normal development, if there is a network request and the Activity is destroyed, it is very likely that the request will successfully return the result to the activity, causing unnecessary troubles such as leakage.

Solution:

You can use ViewModel in combination with onCleared(), call.cancel(), etc.

When the network requests, if the activity is suddenly destroyed, the viewmodel bound to it will also be destroyed. At the same time, we cancel the network connection interface (call.cancel()) in the onCleared() method. Even if there is data returned, the activity will not accept to the notification, because the data is monitored from livedata, and only when livedata triggers an update, the Activity will receive the notification.

(Of course there are many other ways)

2.2. Binding Activity

Here are the following ways:

  • ViewModelProviders.of(this).get(class)(过时)
  • new ViewModelProvider(this,factory).get(class)(常用)
  • new ViewModelProvider.NewInstanceFactory().create(class);

The first way: ViewModelProviders.of(this).get(class)

ViewModelProviders.of(this).get(MyViewModel.class);


implementation "androidx.fragment:fragment:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"

This method is among these dependencies. Of course, if yours is different from mine, it doesn't matter. This is not the point. This method is relatively old, and it can also be found in the source code that the of method of ViewModelProviders actually calls ViewModelProvider and automatically creates a factory.

----------------ViewModelProviders.class----------------

@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
    
    
    Application application = checkApplication(checkActivity(fragment));
    if (factory == null) {
    
    
        factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    }
    return new ViewModelProvider(fragment.getViewModelStore(), factory);
}

The second way: new ViewModelProvider(this,factory).get(class)

ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);

Pass in a system factory. Create creates a new instance, while get searches the HashMap first. If it cannot find it, it creates a new instance. It is also the reason why the reconstructed Viewmodel is the same object. He will put the object in HashMap<String, ViewModel> mMap = new HashMap<>(); in the ViewModelStore class. This method is relatively new and is generally created this way.

public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
    
    
    //第一步:先查找
    ViewModel viewModel = mViewModelStore.get(key);

    if (modelClass.isInstance(viewModel)) {
    
    
        //noinspection unchecked
        return (T) viewModel;
    } else {
    
    
        //noinspection StatementWithEmptyBody
        if (viewModel != null) {
    
    
            // TODO: log a warning.
        }
    }
    //第二步:没有则创建,并保存在mViewModelStore中
    if (mFactory instanceof KeyedFactory) {
    
    
        viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
    } else {
    
    
        viewModel = (mFactory).create(modelClass);
    }
    mViewModelStore.put(key, viewModel);
    //noinspection unchecked
    return (T) viewModel;
}

The third way: new ViewModelProvider.NewInstanceFactory().create(class);

MyViewModel myViewModel1 = new ViewModelProvider.NewInstanceFactory().create(MyViewModel.class);

Write a LiveData below. If you don’t understand LiveData, you can read the previous blog. The table of contents is at the top.

public class MyViewModel extends ViewModel {
    
    
    private MutableLiveData<String> mStr= new MutableLiveData<>();

    public MutableLiveData<String> getmStr() {
    
    
        return mStr;
    }
    public void setmStr(String s) {
    
    
        if(mStr==null){
    
    
            mStr = new MutableLiveData<>();
        }
        mStr.setValue(s);
    }
    @Override
    protected void onCleared() {
    
    
        super.onCleared();
    }
}

all codes

public class JPackActivity extends AppCompatActivity {
    
    

    private ActyJpackLayoutBinding mBinding;
    private MyViewModel myViewModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        //通过databinding 把activity和view绑定
        mBinding = DataBindingUtil.setContentView(this,R.layout.acty_jpack_layout);
        //通过ViewModeProvider 把activity和ViewModel绑定起来。
        myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);

        myViewModel.getmStr().observe(this, new Observer<String>() {
    
    
            @Override
            public void onChanged(String s) {
    
    
                mBinding.textShow.setText(s);
            }
        });
    }
    @Override
    protected void onDestroy() {
    
    
        super.onDestroy();
        //移除观察者
       
    }

3、Fragment

Use the same as in Activity. However, it should be noted that the difference between passing this and getActivity

  • this: This ViewModel is independent and only serves this Fragment alone. Other Fragments cannot obtain the ViewModel with the same memory address.
  • getActivity: The ViewModel scope obtained by using getActivity() is in the Activity and all the fragments it creates, which means that you also get the ViewModel with the same memory address in other Fragments
 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    
    
    // Inflate the layout for this fragment
    MyViewModel myViewModel = new ViewModelProvider(getActivity(), new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
    return inflater.inflate(R.layout.fragment_blank, container, false);
}

Of course, there is another point to note: get("key1",MyViewModel.class);, the get method can pass the key value, and the ViewModel data created by different keys is independent.

4. Summary

It is very simple to use, and you need to practice more so that you will not be stumped by those xx interviewers asking how to implement the steps.

Finally, I would like to share with you a set of "Advanced Materials on the Eight Modules of Android" written by Alibaba's senior architects to help you systematically organize messy, scattered, and fragmented knowledge, so that you can master Android development systematically and efficiently. Various knowledge points.

Due to the large content of the article and the limited space, the information has been organized into PDF documents. If you need the complete document of "Advanced Materials on Eight Modules of Android", you can add WeChat to get it for free!

PS: (There are also small benefits for using the ChatGPT robot at the end of the article!! Don’t miss it)

"Android Eight Modules Advanced Notes"

Insert image description here

Insert image description here

Compared with the fragmented content we usually read, the knowledge points in this note are more systematic, easier to understand and remember, and are strictly arranged according to the knowledge system.

Full set of video materials:

Insert image description here

1. Interview collection

Insert image description here

2. Source code analysis collection

Insert image description here

3. Collection of open source frameworks

Insert image description here
At the same time, a WeChat group chat robot based on chatGPT has been built here to answer difficult technical questions for everyone 24 hours a day .

picture

Guess you like

Origin blog.csdn.net/huahaiyi/article/details/132040300