Introducing MVVM (Model-View-ViewModel) Architecture in Phimpme Android App
Phimpme Android App an image editor app that aims to replace proprietary photographing and image apps on smartphones. It offers features such as taking photos, adding filters, editing images and uploading them to social networks. The app was using MVP(Model-View-Presenter) architecture and is now being ported to MVVM(Model-View-ViewModel) architecture. Advantages of MVVM over MVP? The view model is lifecycle aware and only updates the UI based on the lifecycle of the activity/fragment.Separation of concerns - Not all the code under one single activityLoose coupling - Activity depends on ViewModel and ViewModel depends on the Repository and not the other way around. MVVM? Model - Model represents the data and business logic of the app. The repository can be seen as a model in an MVVM architecture which contains login to fetch the data from an API or a remote APIViewModel - The view model creates a reference with Model/Repository and gets the data for the UI. It delivers the data to UI via observers of LiveData and also the ViewModel is lifecycle aware and respects the lifecycle of the activity such as screen rotations that don’t cause the ViewModel to be created again.View - The Activity/Fragment is the view where the data is shown to the user, the View creates a reference to the ViewModel via ViewModel provider class. Hence it listens to the ViewModel callbacks via LiveData. Process for inclusion Add ViewModel and LiveData implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleVersion"Now create a class AccountViewModel - it will perform all the functioning that will drive the UI of the Account Activity. We will use LiveData for observing the data in the activitypublic class AccountViewModel extends ViewModel {private AccountRepository accountRepository = new AccountRepository();MutableLiveData<RealmQuery<AccountDatabase>>accountDetails = new MutableLiveData<>();//live data }Create a class AccountRepository - Used to perform the DB related operations and the ViewModel will hold the instance of this repository.class AccountRepository {private Realm realm = Realm.getDefaultInstance();private DatabaseHelper databaseHelper = new DatabaseHelper(realm);// Fetches the details of all accounts present in databaseRealmQuery<AccountDatabase> fetchAllAccounts() {return databaseHelper.fetchAccountDetails(); }}Now we will add the functionality in AccountViewModel to fetch accounts for the UI public class AccountViewModel extends ViewModel { final int RESULT_OK = 1;private AccountRepository accountRepository = new AccountRepository();MutableLiveData<Boolean> error = new MutableLiveData<>();MutableLiveData<RealmQuery<AccountDatabase>> accountDetails = new MutableLiveData<>();public AccountViewModel() {}// Used to fetch all the current logged in accountsvoid fetchAccountDetails() { RealmQuery<AccountDatabase> accountDetails = accountRepository.fetchAllAccounts();if (accountDetails.findAll().size() > 0) { this.accountDetails.postValue(accountDetails);} else { error.postValue(true); }}Now in the AccountActivity, we will have the reference of ViewModel and then observe the liveData error and accountDetailspublic class AccountActivity extends ThemedActivityimplements RecyclerItemClickListner.OnItemClickListener {private AccountViewModel accountViewModel;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ButterKnife.bind(this);ActivitySwitchHelper.setContext(this);setSupportActionBar(toolbar);//fetching the viewmodel from ViewModelProvidersaccountViewModel = ViewModelProviders.of(this).get(AccountViewModel.class);initObserver();}private void initObserver() {accountViewModel.error.observe(this, value -> {if (value) { SnackBarHandler.create(coordinatorLayout, getString(no_account_signed_in)).show();showComplete(); } });accountViewModel.accountDetails.observe(this, this::setUpAdapter);} Hence, this completes the implementation of MVVM Architecture in the Phimpme app. Resources Guide to App Architecture - Android Developers BlogViewModel Overview - Android Developers BlogLiveData Overview - Android Developers Blog Link to the Issue: https://github.com/fossasia/phimpme-android/issues/2889Link to the PR: https://github.com/fossasia/phimpme-android/pull/2890
