Malinskiy / SuperRecyclerView

Pumped up RecyclerView
2.63k stars 469 forks source link

Crash on Header adaper example #77

Open super-hu opened 8 years ago

super-hu commented 8 years ago

java.lang.NullPointerException at com.eowise.recyclerview.stickyheaders.HeaderStore.wasHeader(HeaderStore.java:98) at com.eowise.recyclerview.stickyheaders.StickyHeadersItemDecoration.getItemOffsets(StickyHeadersItemDecoration.java:89) at android.support.v7.widget.RecyclerView.getItemDecorInsetsForChild(RecyclerView.java:3653) at android.support.v7.widget.RecyclerView$LayoutManager.measureChildWithMargins(RecyclerView.java:6862) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1396) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2864) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3071) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:584) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525) at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453) at android.widget.FrameLayout.onLayout(FrameLayout.java:388) at android.view.View.layout(View.java:14965) at android.view.ViewGroup.layout(ViewGroup.java:4658) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2162) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1886) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1017) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5967) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) at android.view.Choreographer.doCallbacks(Choreographer.java:574) at android.view.Choreographer.doFrame(Choreographer.java:544) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5032) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method)

cmicat commented 8 years ago

It's a bug in eowise/recyclerview-stickyheaders library, and the library author said the library is Deprecated.

Android official document said public final boolean hasStableIds () "Returns true if this adapter publishes a unique long value that can act as a key for the item at a given position in the data set. If that item is relocated in the data set, the ID returned for that item should be the same." And as we can see, items in "Header Adapter Example" will change after user swipe to refresh the RecyclerView. So I rewrite com.malinskiy.superrecyclerview.sample.StringListAdapter.getItemId to

@Override
public long getItemId(int position) {
    return data.get(position).hashCode();
}

The Problem is that hashCode can have collisions (it return 4bytes int, and promote to 8bytes long) , and UUID is 16bytes, more than 8bytes long.

In my test, the application will not be crashed again by java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference, but I doubt it really solved the problem.

Use guava hash util may ease this problem, but it's still not unique.

I hope someone else can give me a good way to generate stable ids.