livefront / bridge

An Android library for avoiding TransactionTooLargeException during state saving and restoration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does not solve TransactionTooLargeException with android-state library, when enabled globally

budowski opened this issue · comments

When used with android-state library, and when that library is enabled globally (StateSaver.setEnabledForAllActivitiesAndSupportFragments(this, true)) the TransactionTooLargeException still occurs.

Sample code:

MyActivity.java:

    @State
    public String big = new String(new char[1_000_000]);

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Bridge.saveInstanceState(this, outState);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bridge.restoreInstanceState(this, savedInstanceState);
    }

MyApplication.java:

    @Override
    public void onCreate() {
        super.onCreate();

        // If you comment out the following line, it all works properly
        StateSaver.setEnabledForAllActivitiesAndSupportFragments(this, true);

        Bridge.initialize(getApplicationContext(), new SavedStateHandler() {
            @Override
            public void saveInstanceState(@NonNull Object target, @NonNull Bundle state) {
                StateSaver.saveInstanceState(target, state);
            }

            @Override
            public void restoreInstanceState(@NonNull Object target, @Nullable Bundle state) {
                StateSaver.restoreInstanceState(target, state);
            }
        });
   }

StateSaver.setEnabledForAllActivitiesAndSupportFragments(...) is an optimization that avoids having to manually call StateSaver.saveInstanceState/ StateSaver.restoreInstanceState in all of your Activity / Fragment classes. But by doing that and using Bridge you are basically "double-counting" and are still sending all your data to Bridge and to the OS, which triggers the TransactionTooLargeException. Everything about your setup looks fine if you just remove StateSaver.setEnabledForAllActivitiesAndSupportFragments, which you absolutely should if you want to use Bridge and avoid the crash.

To put it another way, what you are currently doing is pretty much the same as doing this:

    @State
    public String big = new String(new char[1_000_000]);

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Bridge.saveInstanceState(this, outState);
        StateSaver.saveInstanceState(this, outState);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bridge.restoreInstanceState(this, savedInstanceState);
        StateSaver.restoreInstanceState(this, savedInstanceState);
    }

That would defeat the purpose of using Bridge, though. So please check one more time that removing the call to StateSaver.setEnabledForAllActivitiesAndSupportFragments not only solves the crash but still manages saved state properly and then close this issue if that's the case. I'll consider adding something to the README to make it clear that this particular optimization for that library shouldn't be used.

Thanks for the quick response!
Yes, looks like it's working properly without that global setting and the exception doesn't occur.

I would add just a note in the README mentioning that you shouldn't use that setting for android-state library.

Sure, thing. I'll look into adding that note 👍