etsy / AndroidStaggeredGrid

An Android staggered grid view which supports multiple columns with rows of varying sizes.
https://github.com/etsy/AndroidStaggeredGrid
4.76k stars 1.13k forks source link

NullPointerException from onSaveInstanceState #93

Open xicabin opened 10 years ago

xicabin commented 10 years ago

The app crash sometimes ( not often ) with the exception below, will anybody tell me how to handle it, thanks in advance ?

java.lang.NullPointerException
    at android.widget.AbsListView.onSaveInstanceState(AbsListView.java:1017)
    at com.etsy.android.grid.ExtendableListView.onSaveInstanceState(Unknown Source)
    at com.etsy.android.grid.StaggeredGridView.onSaveInstanceState(Unknown Source)
    at android.view.View.dispatchSaveInstanceState(View.java:6208)
    at android.view.ViewGroup.dispatchFreezeSelfOnly(ViewGroup.java:1203)
    at android.widget.AdapterView.dispatchSaveInstanceState(AdapterView.java:759)
    at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:1190)
    at android.view.View.saveHierarchyState(View.java:6191)
    at android.support.v4.app.o.f(Unknown Source)
    at android.support.v4.app.o.g(Unknown Source)
    at android.support.v4.app.o.h(Unknown Source)
    at android.support.v4.app.FragmentActivity.onSaveInstanceState(Unknown Source)
    at android.app.Activity.performSaveInstanceState(Activity.java:1046)
    at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1181)
    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2336)
    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311)
    at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2291)
    at android.app.ActivityThread.access$1700(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3683)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:906)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:664)
    at dalvik.system.NativeStart.main(Native Method)
DougSimonton commented 10 years ago

I saw the same stack trace, although with different line numbers. But I think this is just because we are on different android releases. AbsListView tries to access its own local copy of mAdapter during onSaveInstanceState if there is no currently selected item. After trying several things, I found a way to hack around it. The StaggeredGridView doesn't support selection yet, so this hack will work for now.

Add the following private flag and overridden method to ExtendableListView:

private boolean callingSuperSaveInstanceState = false;

@Override
public long getSelectedItemId()
{
    // this is a hack to prevent the superclass (AbsListView) onSaveInstanceState from trying
    // to reference its private mAdapter member, which is always null as this subclass manages
    // its own private mAdapter.  It will skip the call to mAdapter if an item is selected, so
    // fake that here.
    if (callingSuperSaveInstanceState) {
        return 1;
    }
    else {
        // Selection is not supported here yet, so just call superclass
        return super.getSelectedItemId();
    }
}

Then also in ExtendableListView, add code to toggle the flag around the call to super.onSaveInstanceState():

@Override
public Parcelable onSaveInstanceState() {

    callingSuperSaveInstanceState=true;
    Parcelable superState = super.onSaveInstanceState();
    callingSuperSaveInstanceState=false;
337240552 commented 9 years ago

I got this bug too, hope fix it