首页 > 解决方案 > Is the ViewModel responsible for handling all the data related operations of an/a Activity/Fragment?

问题描述

I recently started learning Android Architecture Components (LiveData, ViewModel and Navigation). So I created a bottom navigation application.

I am putting some sample code here just to talk about as an example.

SampleViewModel class:-

public class DashboardViewModel extends ViewModel {

    private MutableLiveData<String> mText;

    public DashboardViewModel() {
        mText = new MutableLiveData<>();
        mText.setValue("This is dashboard fragment");
    }

    public LiveData<String> getText() {
        return mText;
    }
}

SampleFragmentClass:-

public class DashboardFragment extends Fragment {

    private DashboardViewModel dashboardViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel.class);
        View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
        final TextView textView = root.findViewById(R.id.text_dashboard);
        dashboardViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        return root;
    }
}

Let me be clear that there nothing wrong with these pieces of code.

I just want to ask some questions: -

  1. Is the ViewModel fully responsible for loading the data that will be used by an activity or a fragment?

  2. If I need to get some data from the server, would I call the API from ViewModel or the activity itself?

  3. If I need to do some context-based actions, I would do that in the activity or a fragment. Is there some convention or guideline that I should do it in the ViewModel?

标签: javaandroidandroid-jetpackandroid-viewmodel

解决方案


So, let me start with, they are really good questions to ask. And I am happy to answer.

  1. It is YES, if you are following clean architecture e.g MVVM (Model, View, ViewModel). So, in this architecture, your views are really dummy and know nothing of where data is coming. Only thing they do is to show data if data comes. View's only responsibility is to present data, views do not do any business or network logic. On the other hand, ViewModel can be a single source of truth and have one to one relationship with your views (fragment, activity) and ViewModel is lifecycle aware and does handle all the complex and heavy operations. Internally, your view model can have dependency to your repository which has internally dependencies into local data source and remote data source. YES, ViewModel must be single source of truth for your views (activity, fragment) to load data.

  2. As I have written, ViewModel is a single source of truth and it should be the one you can to fetch data from server or local.

  3. It depends on. If it is more UI related job that needs context, you can do it in views. Or if it is heavy computation that needs context such as e.g reading thousands of rows from local database you can do in ViewModel. To get context reference in ViewModel or lower level than it, you can use DI, such as dagger or koin to avoid boilerplate code.

The following diagram from Google is one of the famous one to see high level picture of MVVM architecture.enter image description here

There are so many things to elaborate in this small answer. I think if you check out MVVM architecture you will automatically find all clear answer for your questions and more.

Google hosts a bunch of sample apps for MVVM you may find in the following list.

Sample Apps by Google


推荐阅读