Reading about Android's new Architecture Components, the recommendation is to use various ViewModel instances to feed data to Activities and Fragments.
There's also this notion of driving data from a single persistent model:
The second important principle is that you should drive your UI from a model, preferably a persistent model. Persistence is ideal for two reasons: your users won't lose data if OS destroys your app to free up resources and your app will continue to work even when a network connection is flaky or not connected. Models are components that are responsible for handling the data for the app. They are independent from the Views and app components in your app, hence they are isolated from the lifecycle issues of those components.
And a similar notion of a single source of truth:
In this model, the database serves as the single source of truth, and other parts of the app access it via the repository. Regardless of whether you use a disk cache, we recommend that your repository designate a data source as the single source of truth to the rest of your app.
In the code examples I've seen, they do pass the savedInstanceState bundle up to the super class's implementation, for example:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String userId = getArguments().getString(UID_KEY);
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
viewModel.init(userId);
}
but, it seems like there's no reason any more for our Activities to explicitly store/retrieve important values to/from savedInstanceState.
Is savedInstanceState irrelevant with the new architecture?
it seems like there's no reason any more for our Activities to explicitly store/retrieve important values to/from savedInstanceState.
That would depend entirely upon what is in the activities.
Is savedInstanceState irrelevant with the new architecture?
No.
The idea behind the saved instance state has been, and continues to be, helping the activity pretend as though it had been around all along, even though the activity had been destroyed and recreated along the way, either because of:
So, for example, suppose we have an activity with a form. When the user fills in the form and clicks a "save" action bar item, we want to persist the contents of the form. And, in some cases, we are opening the form on some existing data that is already persisted, and so we want to load that. Those are problems that the Android Architecture Components, particularly Room, are designed to help with.
But, suppose the user fills in a field on the form, then rotates the screen. In this case, most likely we do not want to save the change in the database yet, because the user has not clicked "save" to express interest in persisting this change. So, we rely on onSaveInstanceState()
to handle that for us. In this case, the built-in onSaveInstanceState()
handles this, as the contents of an EditText
is obvious user-mutable state.
But, suppose in addition, after editing the field, the user taps on an ImageButton
to choose a contact. That uses ACTION_PICK
to bring up the contacts picker, and the user chooses a contact there. Control returns to the original activity, which perhaps has a TextView
to show the contact's name, or perhaps updates the ImageButton
with the contacts avatar. Now the user rotates the screen. Once again, we may not want to persist this yet. However, this time, the activity is not going to automatically hold onto the Uri
of our contact, as it does not know how to. So, we put that in the saved instance state Bundle
ourselves, overriding onSaveInstanceState()
.
Data stores (e.g., databases) represent the single "source of truth", but it is application logic that decides when data becomes "truth", and instance state is a common approach for handling data that may become truth in the future but is not truth yet.