ViewModel class and the general features associated with it are parts of Android Architecture Components – a set of experimental features for Android that were announced by Google at Google IO 2017 conference.

On the surface, the purpose of ViewModel looks very legitimate – it can be used in order to “tie” data to the logical scope of either Activity or Fragment.

The scope being logical means that it remains the same even if e.g. Activity is destroyed and then re-created upon rotation. This should make it easy to retain data in Activities and Fragments upon configuration changes.

Sure thing we all need this feature! Like, yesterday!

Comparison of ViewModel to the “old” approach:

But let’s take a step back for a moment.

How did we retain data in e.g. Activity upon configuration change until now? The following code snippet demonstrates the “old” approach:

public class OldApproachActivity extends Activity {

    private static final String USER_ID = "USER_ID";
    private static final String PRODUCT_ID = "PRODUCT_ID";

    private String mUserId;
    private String mProductId;

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mUserId = savedInstanceState.getString(USER_ID);
            mProductId = savedInstanceState.getString(PRODUCT_ID);

    protected void onSaveInstanceState(Bundle outState) {
        outState.putString(USER_ID, mUserId);
        outState.putString(PRODUCT_ID, mProductId);


For comparison, retaining the same variables during configuration change using ViewModel could be done like this:

public class ViewModelActivity extends Activity {

    private MyViewModel mViewModel;

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

    public static class MyViewModel extends ViewModel {
        private String mUserId;
        private String mProductId;


If we would need to decide which approach is better based on the simple samples above, it is only natural to choose the one involving ViewModel. It is shorter and clearer.

The no-so-evident gotcha, however, is that the above two code snippets are not functionally equivalent!

During “normal” interaction of the user with the application both approaches produce the same result, but the “old” approach also supports “save and restore” flow, whereas the one involving ViewModel doesn’t.

Save and Restore Flow:

As described in the official documentation, application’s process can be killed by Android at any time due to low memory conditions. Using this mechanism Android can reclaim the resources consumed by applications when it needs them.

In most cases, Android will notify the process that it is about to be killed, thus giving it a chance to save application’s state. Then, when the application is started again (either due to user interaction or automatically), it will be given an opportunity to restore its previous state. This flow is called “save and restore”.

Let’s review one specific example.

Suppose that the application have a back stack of Activities when Android decides to kill it.

Before killing the application, Android will call onSaveInstanceState(Bundle) method of each Activity on the back stack. Developers need to use the provided Bundle in order to persist data that will allow to restore the state of each Activity in the future.

In addition, Android will automatically save the state of the back stack itself (i.e. which Activities are shown and their ordering).

When the application is restarted, the system will automatically restore the previous state of the back stack. User can then navigate back to all Activities that had been present on the back stack when the application was killed, and Android will automatically recreate them.

When Activities from the back stack are being recreated, Android passes the respective saved data to onCreate(Bundle) methods. This saved state data can be used by developers in order to restore the state of each Activity.

The process of save and restore of each Activity can be roughly summarized as follows:


Correct implementation of “save and restore” flow allows the user to have a fluent experience that is not affected by Android’s memory management activities.

If you go back and read the code demonstrating the “old” approach above, you will notice that in addition to supporting configuration changes, it also supports save and restore flow. In case of the new approach involving ViewModel, however, save and restore flow results in loss of developer managed state.

Note that I wrote “developer managed state”. Android will always do its part and restore the state it is responsible for. It is only the state kept in ViewModel that will not be restored.

This state inconsistency is much worse than not restoring any state at all. Imagine that the user can navigate back to previous Activities, but their state was restored only partially (e.g. some references that must not be nullable during normal operation are nulls).

In such a case, you will be lucky if application just crashes with NPE. Then, at least, the user will know that something bad happened and have a chance to start application from scratch.

Much worse if the application does not crash, but the user is stuck with e.g. infinite progress indication or inconsistent UI. The worst of all scenarios is if the application seems to be working, but silently corrupts user’s data.

The video below demonstrates a bug related to save and restore flow that I found in the new StackOverflow application for Android:

Keep in mind that this is the least dangerous of all the save and restore bugs – just user interface inconsistency, followed by application’s crash.

Why Care About Save and Restore Flow:

Some developers argue that save and restore is such a rare scenario, that it can be ignored until proven otherwise.

Other developers don’t go as far as ignoring save and restore, but still say that if it occurs then it means that the user haven’t interacted with the application for a long time. In this case, they say, we can just assume that previous state is outdated anyway and restart the application from scratch.

You might’ve heard additional forms of this argument. The assumption underlying all these claims is that save and restore does not occur very often.

The reality, however, is that save and restore flow is being constantly experienced by majority of your users.

It is true that people who own modern flagship devices with huge amounts of RAM couldn’t care less about save and restore, but I experience save and restore on a daily basis on my personal Samsung Galaxy S4 having 2GB of RAM.

Take a look at this chart from AppBrain showing the most used Android phones as of May 2017:

Most used Android phones

Note how your average user is more likely to have Samsung Galaxy S3 than Samsung Galaxy S7 Edge. Also note that the second most used phone is Samsung Galaxy Grand Prime which has just 1GB of RAM! Given that Samsung phones are on the high performance side, users of other phones are most likely to have similar or even smaller amounts of RAM.

Think about it – a huge amount of your users (probably above 50%, unless you have a niche market) own phones that have less than 2GB of RAM.

On my Samsung Galaxy S4, which has 2GB of RAM, Android starts killing applications after I have approximately 10 applications open in background. Your average user will have more than that.

Therefore, handling of save and restore flow is not optional. Professional Android developers who care about their users must implement a first class support for save and restore in their applications.

Equipped with this knowledge we can get back to architecture components.

Usefulness of ViewModel:

In the previous section we saw that support for save and restore flow is not optional and must always be implemented. Earlier we saw that implementation of save and restore also handles configuration changes.

So, why would we want to use ViewModel then?

There is one use case for ViewModel that was stated by many developers. Since it seems to be so resonating with the community, let’s discuss it in details.

Turns out that there is an upper limit on the amount of data that can be stored during save and restore flow. I couldn’t find the exact number, but looks like it is at approximately 500kB. If you attempt to save more than 500kB of data during onSaveInstanceState() call, you will be presented with TransactionTooLargeException.

In this situation it becomes very tempting to use ViewModel in order to retain big data sets during configuration changes.

In my opinion, under no circumstances should large data sets be “stored” in either Activities or Fragments. Let me explain why using two imaginary scenarios.

Imagine that the user interacts with Activity and fetches 1MB of data from the web. If all this data is stored in Activity then when the user clicks “back” button and navigates to the previous screen this data is lost. If at this point the user decides to open the same Activity again, then all the data will need to be re-fetched from the network. This network call duplication due to a simple back-and-forth between screens is not a very good design.

Now imagine that we implement search functionality. In this case, even if the user searches for the same string, we must still fetch a new data from the network upon each search request. We are not concerned with back-and-forth between screens anymore because we hit the network anyway. It might seem that storing search results in Activity is a valid design choice in this case, but imagine that you discover at some point that you need the search results in other part of the application. The fact that search results are stored in Activity becomes an obstacle because there is no reliable way to access them outside of this Activity.

The above examples show that while ViewModel can be used in order to retain large data sets upon rotation, it is probably a bad design choice to start with. The fact that it can be done doesn’t imply that it should be done.

The only state that should be stored in Activities and Fragments is UI state and data identifiers.

Large data sets should be stored in Application scope, or, depending on the requirements, persisted to SQLite or some other persistent storage.

Since there is no clear valid use case for ViewModel Architecture Component, its introduction can be hardly justified.

ViewModel Architecture Component Considered Harmful:

In the previous section we discussed why ViewModel is somewhat useless addition to developer’s toolbox. However, I think that it is not just useless, but harmful.

As I said earlier, many developers (especially inexperienced ones) don’t realize the importance of proper save and restore support. But even when save and restore support is implemented, it is rarely included in the testing plan.

[There is a widespread myth that testing save and restore is difficult because there is no easy way to cause the process to be killed in background. On my phone it is very simple: go to Developer Options and set “limit background processes” option to 1.]

While save and restore support is often neglected and rarely tested (in my experience; YMMV), configuration changes support is commonly implemented and tested. In fact, any application that is not locked to portrait mode will be thoroughly tested in context of configuration changes.

Until today, the fact that support for configuration changes also provided support for most parts of save and restore flow (not all, unfortunately) mitigated the problem a bit. And even when bugs with save and restore were found, they could be fixed while keeping the general design intact.

Introduction of ViewModel changes the situation cardinally. Now developers will be able to implement support for configuration changes while completely ignoring save and restore flow.

It doesn’t take too much imagination to see that the following two step scenario will take place on many projects:

  1. Application is released without save and restore support. Users are being bombarded by save and restore bugs.
  2. Upon realization of the problem, developers “hack” save and restore support alongside ViewModel approach.

The immediate result of lack of save and restore support will be user facing bugs. Some of them might be as innocent as NPE crashes, others might silently corrupt users data.

Assuming best case scenario of application crashes, developers will be able to quickly identify the issues using various “crashlytics” tools. If the application will just hung or silently corrupt user’s data, then developers will need to investigate the problem based on 1-star user reviews in Google Play.

Once the root cause of the bugs will be identified, save and restore support will need to be implemented. However, it is not likely that developers will refactor the applications in order to get rid of ViewModel – at this point it will be too risky and time consuming. Therefore, save and restore support will be just hacked on top of the existing design. The result of these hacks will be long term maintainability issues and more bugs.

And there is more to it. Since it is so simple to retain data in Activities and Fragments using ViewModel approach, the average amount of memory consumed by applications will increase. Even if different components will need access to the same data, it will be very easy to have each of them to retain its own dataset.

Applications will consume more memory, which will lead to more frequent killing of processes by Android, which will lead to the bugs in save and restore to affect even more users.


In this post we saw how important it is to handle save and restore flow and how introduction of ViewModel can negatively impact the users of our applications. Especially the users who own older or lower end devices.

Please leave your comments and questions below, and consider subscribing to our newsletter if you liked this post.

This article has 18 comments

  1. Riley Ackerman Reply

    ViewModel is only useless if you use it to persist state of small objects. If you are holding very large objects in memory (anything 0.5 MB or greater), then it is to persist state across configuration changes as it helps avoid the TransactionTooLargeException.

    An ideal implementation would be to save an identifier of large objects in instance state and use ViewModel to persist the object across rotations. In this manner, we get fast and cheap object persistence across configuration changes, but still have the ability to recover from process/activity death.

    • Vasiliy Reply

      I would argue that TransactionTooLargeException is a hint that it is time to have a critical look at your design, rather than a sign that ViewModel is required.

      Let’s say you use ViewModel like you said. If user navigates back and then opens the same activity again, the data will not be there. So, if ViewModel was the only mechanism you used in order to store 0.5MB of data – all this data will need to be re-fetched and re-processed just because the user made a simple back-and-forth navigation between screens. This design is not optimal and should be reviewed.

  2. Tony Reply

    One other benefit of ViewModels not outlined here is transient/non-config instances, e.g. Threads or network requests.

    I agree that using ViewModels might cause devs to overlook Config saving, and that is something that needs to be more explicitly addressed in the Arch Components. However, ViewModels in this paradigm allows for better code fluidity between Activity instances. VMs allow holding on to necessary & long-lived transient objects without hot-swapping callbacks or incorporating a temp cache strategy to handle config-changes appropriately.

    • Vasiliy Reply

      Hi Tony, thanks for your comment.
      You’re right that ViewModel can allow for relatively easy “sharing” of e.g. network requests between instances of the same Activity on config changes. However, in order to do this ViewModel will need to have a reference to these network requests.
      This might not be evident immediately, but if you try to implement this approach in code you will notice that parts of business logic start leaking into ViewModel. The more such parts you’ll have, the more you will contaminate the ViewModel with logic.
      Such a contamination is not in line with the main purpose of MVVM: separation between business and presentation logic. It is, in essence, just a quick and dirty hack that will have negative impact on maintainability of your project. Therefore, while what you say can be done, I doubt that it should be done.
      What’s your alternatives? From the top of my head:

      1) Encapsulate network requests in classes that “live” in Application scope.
      2) Encapsulate network requests in Services
      3) Encapsulate network requests in Sync Adapter, JobScheduler, etc.

      All of these alternatives require more work, but this is a classical engineer’s dilemma: do it quick and dirty, or do it right. In my experience, quick and dirty is never a good idea.

  3. Pa Reply


    I do not understand the comparison between ViewModel and the “Save and Restore flow”. Simply put, IMHO these facilities are meant to be used in different contexts. Before ViewModel was there an easy way to preserve state on configuration changes? It was a nightmare with retained fragments for example. It was more easy to forget to handle some lifecycle flows, propagate data between fragments and activities and so on. Not to mention other approaches… In any case propagating state between activities instances using OnSaveInstanceState was and, as you said, is necessary. I think that the ViewModel covers a huge missing part of the Android platform (not to mention the possibility to be able to observe data, share live data between fragments without worrying in almost all cases to register/deregister listeners and so on). Surely it is perfectible as everything. How would you improve/replace it?


    • Vasiliy Reply

      Hi, thanks for your comment.
      You are right – ViewModel and save and restore flow are different contexts. This is exactly the major deficiency of ViewModel that I tried to show in this post.
      If you think about it conceptually, then save and restore and config changes require the same functionality – preserve data upon Activity (or Fragment) being destroyed and re-created.
      It doesn’t make sense to use two completely different approaches in order to achieve the same functionality. If you do use both (and I invite you to try to do it in a real application, not artificial examples), you will notice that it involves more effort and results in more complex design. It also gives rise to corner case scenarios related to integration between these approaches, which means that there will be more bugs.
      If you do use both, you’ll have a very bad design, but, at least, be covering both bases. My main problem with ViewModel is that it makes it very easy to forget about save and restore completely and handle only config changes. You might be an experienced developer who knows how to implement and test save and restore support, but many developers don’t. This means that users will get more save and restore bugs.
      For example of save and restore bug in StackOverflow (!) application see this video:

  4. Marco Reply

    I agree with you Vasiliy.
    Today I tried for the first time the codelab on ViewModel and, since I’m an experienced developer, the first thing I asked myself was: let’s try to enable the “Don’t keep activity” flag and see if it works. And the result was quite disappointing to me…

  5. Galeen Reply

    What is the difference between ViewModel and standard Singleton class that can hold the data until you decide to clear it and will be wiped on App killed by the OS?

    • Vasiliy Reply

      You can think of ViewModel as a “mini-Singleton” which lives in Activity/Fragment logical scope and will be wiped when the respective logical scope ceases to exists.

      • Andrei Mishchenko Reply

        It’s completely wrong statement.
        ViewModel has nothing with Singleton, because system controls Lifecycle of ViewModel fragment. Otherwise any activity/fragment would considered as this mythic “mini Singleton”.

        • Vasiliy Reply

          Hello Andrei,
          I guess it is a matter of interpretation.
          ViewModels are very much like Singletons because you obtain a reference to them using static method calls, and, as long as logical scope is not destroyed, all these calls will result in the reference to the same object.
          To my best knowledge, Activities/Fragments are not being cached and retrieved through static method calls, therefore, I would say, you probably misunderstood the argument.

          • Andrei Mishchenko

            It’s not like Singleton, because you don’t have any static reference to ViewModel, and even don’t have any app level reference. ViewModel.get is just provider that creates a new instance or returned cached instance from Fragment manager.
            So it’s just incorrect to try consider VM as any kind of Singleton, because it doesn’t work as Singleton but on application level + temporary, application aware cashing

          • Andrei Mishchenko

            And Fragments of course cached by fragment manager and VM uses the same API.

            Activities also cached, system keeps your activities alive in task stack, but can kill them at any moment, but practically does that not so often for modern Android devices

  6. Andrei Mishchenko Reply

    Of course, ViewModel doesn’t persist anything with don’t keep activities mode.
    But from other point of view, system never manage activities like don’t keep activities, it’s useful but synthetic tool, that can show problems of your app with state, but VM never considered as replacement for data persistency or caching

  7. Andreas Reply

    ViewModel is a term from programming architecture to seperate view from model it is NOT a way to replace the onSaveInstanceState that should still be used to save the data (in the ViewModel off course as no IO operations should be handled in an activity or fragment). This article do more damage than good for new programmers to understand the fundamentals of programming architecture.

    I advise you to read some literature on the MVVM architecture and revise this article after that.

    • Vasiliy Reply

      Hello Andreas,
      Thanks for joining the discussion.
      I do agree that “view model” is a term related to presentation layer architecture. However, ViewModel architecture component is not directly related to MVVM in any way and can be used with any other approach as well (MVP, MVC, “all code in Activity”, etc.). I touched on this subject in this talk and you can watch it to get a more complete picture.
      We can all agree (hopefully) that proper naming is important. Therefore, this is yet another major issue with ViewModel – it is a misleadingly named library.

      So, I will take part of your advice.
      I don’t think that I really need to read any more literature on MVVM. See, I’ve been publishing very comprehensive articles about MVx architectures in Android for years. Therefore, I believe that I have a very deep understanding of presentation layer architectures.
      However, I will revise this article and mention that ViewModel architecture component is misleadingly named and is not related to MVVM in any way.

      • Andreas Reply

        You state that the Android user should choose between onSaveInstanceState and ViewModel that is simply not a valid statement.

        • Vasiliy Reply

          Andreas, I think you misunderstood the article a bit.
          What I said is that Android developers must implement support for save&restore regardless of whether they use ViewModel or not. Therefore, there is no “choice between onSaveInstanceState and ViewModel”.

          The only choice is to use ViewModel in addition to onSaveInstanceState or not. This article lists reasons to avoid it.

Leave a Comment

Your email address will not be published. Required fields are marked *