Read more about the article Introducing MVVM (Model-View-ViewModel) Architecture in Phimpme Android App
Introducing MVVM in Phimpme

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

Continue ReadingIntroducing MVVM (Model-View-ViewModel) Architecture in Phimpme Android App

Smart Data Loading in Open Event Android Orga App

In any API centric native application like the Open Event organizer app (Github Repo), there is a need to access data through network, cache it for later use in a database, and retrieve data selectively from both sources, network and disk. Most of Android Applications use SQLite (including countless wrapper libraries on top of it) or Realm to manage their database, and Retrofit has become a de facto standard for consuming a REST API. But there is no standard way to manage the bridge between these two for smart data loading. Most applications directly make calls to DB or API service to selectively load their data and display it on the UI, but this breaks fluidity and cohesion between these two data sources. After all, both of these sources manage the same kind of data. Suppose you wanted to load your data from a single source without having to worry from where it is coming, it’d require a smart model or repository which checks which kind of data you want to load, check if it is available in the DB, load it from there if it is. And if it not, call the API service to load the data and also save it in the DB there itself. These smart models are self contained, meaning they handle the loading logic and also handle edge cases and errors and take actions for themselves about storing and retrieving the data. This makes presentation or UI layer free of data aspects of the application and also remove unnecessary handling code unrelated to UI. From the starting of Open Event Android Orga Application planning, we proposed to create an efficient MVP based design with clear separation of concerns. With use of RxJava, we have created a single source repository pattern, which automatically handles connection, reload and database and network management. This blog post will discuss the implementation of the AbstractObservableBuilder class which manages from which source to load the data intelligently Feature Set So, first, let’s discuss what features should our AbstractObservableBuilder class should have: Should take two inputs - disk source and network source Should handle force reload from server Should handle network connection logic Should load from disk observable if data is present Should load from network observable if data is not present is disk observable This constitutes the most basic data operations done on any API based Android application. Now, let’s talk about the implementation Implementation Since our class will be of generic type, we will used variable T to denote it. Firstly, we have 4 declarations globally private IUtilModel utilModel; private boolean reload; private Observable<T> diskObservable; private Observable<T> networkObservable;   UtilModel tells us if the device is connected to internet or not reload tells if the request should bypass database and fetch from network source only diskObservable is the database source of the item to be fetched networkObservable is the network source of the same item Next is a very simple implementation of the builder pattern methods which will be…

Continue ReadingSmart Data Loading in Open Event Android Orga App