17

I'm with some doubts regarding the state save using MVP on Android. I defined my fragments/activities as views and then implemented the corresponding presenters.

My example is simple:

I have a activity with some checkboxes and spinners. If the activity is destroyed by the Android system and then recreated, where should I save these spinners and checkboxes states? On the view? On the presenter?

If on the view, should I have the restore logic on the view or on the presenter?

Thank you!

Fábio Carballo
  • 3,245
  • 5
  • 26
  • 36

5 Answers5

3

In the case of MVP, is the model who is in charge of keeping the state of the view.

For example, in you model you have a Post entity with an Array of Categories. In your view you have a Checkbox for each category, and in each checked/unchecked action you add/remove objects from the Post's Category array.

Once the Activity is restored, the View should ask for the Post's Category array in order to find out which are selected and which aren't, so it can set the proper checked/unchecked attribute.

Here's a really good post about it: http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/

mmark
  • 1,204
  • 12
  • 19
  • I understand, but my example is a form of creation. So my model could be a Post with Categories. The problem is that I never save the post object. The goal is to create a post object and use it to make a web request. So, I guess the only way that I have of doing it is to store in the view and then recreate the state of the view. Am I wrong? @mmark – Fábio Carballo May 20 '15 at 14:27
  • 1
    @FábioCarballo if i not misunderstanding the goal of MVP, you won't need to save the Post object (by "save" i assume you mean something like a local db or SharedPreferences). The presenter+the model are the one who should persist (in memory) across the view state changes – mmark May 20 '15 at 14:54
2

The Presenter is an interface between the Model and the View and shouldn't take any responsibility for saving any state. It makes more sense to let either the Model or the View handle state:

  1. Model. Presenter is responsible for populating the View with Model data during activity initialization and commits all View interactions to the Model immediately. Model is always kept up to date, so config changes are irrelevant.
  2. View. Presenter is responsible for populating the View with Model data during initialization, however the View saves and restores it's own state across configuration changes. This makes sense in a create/edit situation where a 'Save' button exists and you have a transient Model (or Working Model).

The latter approach makes sense when a 'Save' button exists. The Presenter is not involved either way.

Rich Ehmer
  • 2,764
  • 23
  • 18
1

1. Save & Restore View State in View (Activity / Fragment).

I prefer saving & restoring view's state in View itself (Activity / Fragment)

Hence it the responsibility of view to save its state (Hence adhere to single responsibility principle).

Example

/**
 * On Save Instance State.
 *
 * @param outState Out State.
 */
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(STATE_KEY_USERNAME, getUserNameFieldValue());
    outState.putString(STATE_KEY_PASSWORD, getPasswordFieldValue());
    outState.putBoolean(STATE_KEY_REMEMBER_ME, getRememberMeFieldValue());
}

/**
 * On Restore Instance State.
 *
 * @param savedInstanceState Saved Instance State.
 */
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState != null) {
        String userName = savedInstanceState.getString(STATE_KEY_USERNAME, "");
        String password = savedInstanceState.getString(STATE_KEY_PASSWORD, "");
        boolean rememberMe = savedInstanceState.getBoolean(STATE_KEY_REMEMBER_ME, false);

        userNameEditText.setText(userName);
        passwordEditText.setText(password);
        rememberMeCheckBox.setChecked(rememberMe);
    }
}

2. Save & Restore Presenter State in Presenter

If you need to save any state of the presenter then do it in presenter.

My Base presenter will look this

 /**
 * On Create View.
 * <p>
 * 1. Gets called from view's onCreate method.
 *
 * @param view          View.
 * @param savedInstanceState Saved Instance State.
 */
void onCreateView(final View view, final Bundle savedInstanceState);

/**
 * On Attach View.
 * <p>
 * 1. Gets called from view's onStart method.
 */
void onAttachView();

/**
 * On Detach View.
 * <p>
 * 1. Gets called from view's onStop method.
 */
void onDetachView();

/**
 * On Save State.
 * <p>
 * 1. Gets called before view is destroyed to save the state of the presenter.
 *
 * @param outState Bundle in which to place your saved state.
 */
void onSaveState(final Bundle outState);

/**
 * On Destroy View.
 * <p>
 * 1. Gets called from view's onDestroy method.
 */
void onDestroyView();
Vasanth
  • 6,257
  • 4
  • 26
  • 19
0

Maybe this helps: https://github.com/Yarikx/reductor. It is a predictable state container inspired by JavaScript's Redux.

pavle
  • 909
  • 14
  • 38
0

This can be acheived by using concept of stateful presenters where the presenter is made aware of the state. Here is a great demonstration I found online: https://pspdfkit.com/blog/2016/restoring-state-in-android-mvp-architecture

this helped me maintain a clean MVP architecture while being able to restore and save view(activity/fragment) state

Hari Kiran
  • 188
  • 13