livefront / bridge

An Android library for avoiding TransactionTooLargeException during state saving and restoration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Failing to initialize Bridge

neliousness opened this issue · comments

I have followed your instructions carefully but I keep getting the following error

java.lang.IllegalStateException: You must first call initialize before calling any other methods

i seem to have found the problem. i thought that i could initialize it from my Splash screen activity or my main activity. I got it to work by adding it in the activity that i used to declare the state i wanted to store.

@neliousness My recommendation is to subclass Application and do the initialization there:

public class YourApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // initialize Bridge here
   }

}

Then just make sure your application points to that subclass on startup. In AndroidManifest.xml:

    <application
        android:name=".YourApplication"
        ...

@neliousness I'm going to close this issue out as resolved.

Hello, I have a similiar problem with Bridge and I reaIly don't know how to figure out this issue. I have a subclass of Application class which is added in Manifest.xml :

<application
    android:name=".analytics.AnalyticsApp"
    ...

In this class I initialize Bridge:

public class AnalyticsApp extends MultiDexApplication {

    ...

    @Override
    public void onCreate() {
        super.onCreate();
        Fabric.with(this, getCrashlytics());

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

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

     ...

    }

    ...

}

But on some devices users have an application crash caused by Bridge:

Fatal Exception: java.lang.IllegalStateException
You must first call initialize before calling any other methods

image

Any ideas why this crash is happen? And why It happen not on every device (for example mine) ?

I would be a grateful for any advice. Thanks

@Kaszmir Hmm that definitely seems very odd. One thought I have is that you can try moving the Bridge.initialize call to before super.onCreate. I'm guessing there is somehow some kind of race condition between Activities being restored while the Application.onCreate method is running. That shouldn't happen but for some reason in these cases it might be. I'd say to give that a shot and see if it helps. Otherwise, if there are any logs or more steps you could find to try to consistently reproduce this, I could look into it further. I could also probably check make the the singleton construction more thread-safe.

@Kaszmir I'll note that one thing I definitely find strange is that it's a call to Bridge.saveInstanceState that is causing the problem. That actually makes it seem like my race condition theory probably isn't what's happening. Is there anything unusual in your usage of Bridge.saveInstanceState that could be at all related? Is it called anywhere other than the onSaveInstanceState method of an Activity / Fragment?

@byencho Thanks for reply. I'll try to move Bridge.initialize call before super.onCreate.
About your second comment: Bridge.saveInstanceState is called via presenter but only when onSaveInstanceState is called in my Fragment

this is code from Fragment

@Override
public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if(presenter == null) {
       return;
  }
  presenter.saveVars(outState);
}

and this is code from presenter:

@Override
public void saveVars(Bundle outState) {
  if (this.recordingsData != null) {
       Bridge.saveInstanceState(this, outState);
   }
}

Do you think that there might be a source of problem?

@Kaszmir Hmm...so that setup in the presenter looks fine, so I wouldn't think that is the case. Do you know where in your code the Bridge.saveInstanceState call is happening that is actually triggering the crash that you see?

@byencho yes, it's exactly when SaveVars() method is called from Fragment on Presenter and Presenter after check if data to save isn't null tries to call saveInstanceState() on Bridge. It's a code snippet that I posted in my last comment. This trigger a crash. But definetly not every time because on my phone I can't reproduce it

@Kaszmir Ah OK good to know. Yeah I'm still not really sure what's going on there since nothing seems very strange in that usage. Let me know if you notice any change when you move the call to before super.onCreate() or if you find out any other information.

Quick question, though : you aren't using some custom "Fragment manager" library are you for managing your Fragments? Just the vanilla FragmentManager from the OS? I only ask because I've seen bugs before from quirks in these kinds of libraries that are hard to work around.