Crash on Header adaper example
super-hu opened this issue · 1 comments
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)
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.