Search code examples
androidandroid-activityviewmodelandroid-lifecycle

Preserve data through memory cleaners


I have an issue with the preserving bundled data of an Activity. Certain memory cleaners (such as clean master), as well as the GC of certain devices seem to remove all of the data, and bundled data, from an activity and corresponding ViewModel causing the activity to crash.

My question is: is there a way to hold to the data (usually passed via bundle) required for the activity to load?

I have tried solutions to try and preserve the data via onSavedInstanceState

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt(BUNDLE_ARGUMENT_CUSTOMER_ID, this.mViewModel.getCustomer().getId());

    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    if (savedInstanceState != null) {
        this.mViewModel.setCustomer(new Customer(savedInstanceState.getInt(BUNDLE_ARGUMENT_CUSTOMER_ID, -1)));
    }
}

As well as rely on ViewModel to keep the data alive, none of which have worked. However, the only solution so far that actually works is to save data to a local storage (either using SharedPreference or InternalStorage), which open certain other issues of additional management of data. Even after saving the data, the effect of the application is as if an crash occurred when navigation through the back stack.


Solution

  • Unfortunately you will HAVE to use some form of more permanent storage like a file or SQLite as the whole point of those "cleaners" is to reclaim resources being used.
    You can optionally store the data in a cloud provider(like firebase) and request it. firebase gives you a gb of data to store on the free tier. It is overhead though, I highly recommend just using a file or SQLite. it's a best practice you will need to adopt

    In any case it is not your fault that the user is putting these cleaners on their phones, you just have to manage your app's lifecycle gracefully

    One option is to disable history so user cannot navigate the back stack. another option is to always ensure data is loaded in memory before trying to display it and displaying an error message in case data is getting erased prematurely. you can detect other applications installed on the user's device and inform them that usage of those applications will crash YOUR app(but I don't recommend this as it adds permissions overhead that will decrease number of people who're willing to download your app)