idanatz / OneAdapter

A Viewholderless Adapter for RecyclerView, who supports builtin diffing, states (paging, empty...), events (clicking, swiping...), and more.
MIT License
470 stars 45 forks source link

Inconsistency detected. Invalid view holder adapter positionViewHolder #3

Closed patrykserek closed 4 years ago

patrykserek commented 5 years ago

I followed a basic usage tutorial and I got a exception:

Process: com.example, PID: 13642
    java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{232efed position=2 id=-969824770, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{3f2d670 VFED..... ......I. 0,0-1080,1516 #7f0900e6 app:id/recyclerView}, adapter:com.idanatz.oneadapter.internal.InternalAdapter@65b9de9, layout:androidx.recyclerview.widget.LinearLayoutManager@a556a6e, context:com.example.MainActivity@6c3203e
        at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5953)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6137)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6097)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6093)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4066)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3515)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:24510)
        at androidx.recyclerview.widget.RecyclerView$LayoutManager.measureChildWithMargins(RecyclerView.java:9352)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1653)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4115)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3521)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChild(ViewGroup.java:6799)
        at androidx.viewpager2.widget.ViewPager2.onMeasure(ViewPager2.java:482)
        at android.view.View.measure(View.java:24510)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24510)
        at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1414)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.widget.ScrollView.onMeasure(ScrollView.java:452)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
        at android.view.View.measure(View.java:24510)
2019-08-13 12:33:05.879 13642-13642/com.example E/AndroidRuntime:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:736)
        at android.view.View.measure(View.java:24510)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3004)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1833)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2122)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7595)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
        at android.view.Choreographer.doCallbacks(Choreographer.java:790)
        at android.view.Choreographer.doFrame(Choreographer.java:725)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7319)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)

Below you can find my classes.

Model:

class Model(private val id: Long) : Diffable {

    override fun areContentTheSame(other: Any) = other is Model && other.id == id

    override fun getUniqueIdentifier() = id
}

ItemModule:

class ExampleItemModule : ItemModule<Model>() {

    override fun onBind(model: Model, viewBinder: ViewBinder) {
        //unused for now
    }

    override fun provideModuleConfig(): ItemModuleConfig = object : ItemModuleConfig() {
        override fun withLayoutResource() = R.layout.example_item
    }

}

Adapter initialization:

recyclerView.layoutManager = LinearLayoutManager(context)
val oneAdapter = OneAdapter()
        .attachItemModule(ExampleItemModule())
        .attachTo(recyclerView)

oneAdapter.setItems(listOf(Model(1L), Model(2L)))

I execute all of the code on the main thread, so modification on the background thread is not the reason for the exception. I would be very grateful if you consider my request ASAP.

idanatz commented 5 years ago

Hi

I've created a new project with your code samples and sadly could not reproduce this behavior. you can check the project here: https://drive.google.com/file/d/1Wnd-k2W1eW6Xak3PuHSlBwTbPPX8eoQK/view?usp=sharing tell me if you can run it or having the same issue.

Is this issue happens in OneAdapter's sample application? https://github.com/ironSource/OneAdapter/tree/master/sample

OfTheWolf commented 4 years ago

I had the same problem only happens in real device. it occured when i use nested recyclerViews so creating OneAdapter instance in my item module for horizontal recycler view row was the cause. I removed that part and used regular Recycler adapter. It worked that way.

StepanMynarik commented 4 years ago

Same problem here :( And also with the nested recycler view. Shame the only solution seems to be not using the OneAdapter.

StepanMynarik commented 4 years ago

Various causes for this exception can be seen here. Is there some hotfix for this? Otherwise I will have to use a different adapter. And that would be sad. I like OneAdapter a lot. It is super clean and just nice. BTW Thanks for reopening this issue.

idanatz commented 4 years ago

This crash is one of the trickiest to track find and fix, it's very generic. Can you please share a minimal project as possible that produces this bug with a nested RecyclerView?

idanatz commented 4 years ago

I reproduced the bug and it will be fixed in the next version. hopefully will be released tomorrow :)

OfTheWolf commented 4 years ago

@idanatz when i set itemAnimator = null the bug is fixed for now. maybe it helps.

Edit: It is not nested in this case btw.

idanatz commented 4 years ago

Version v1.4.0 is out with the fix, really hope it would solve your issues. Please check the CHANGELOG and the README.

francescogatto commented 3 years ago

Hi, i have the same problem with the 2.0.1 version. it happens only in huwaei devices.. here the log:

atal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{12a69d5 position=1 id=8843833539784609743, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{1b55053 VFED..... ......ID 48,1019-1032,1506 #7f090304 app:id/recyclerView}, adapter:e.e.a.c.b@bdead90, layout:androidx.recyclerview.widget.LinearLayoutManager@411f689, context:+MainActivity@b082bdb at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5974) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6158) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118) at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114) at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303) at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627) at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587) at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665) at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4085) at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3849) at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1816) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1660) at android.widget.LinearLayout.onLayout(LinearLayout.java:1569) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1855) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1263) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1816) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1660) at android.widget.LinearLayout.onLayout(LinearLayout.java:1569) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1816) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1660) at android.widget.LinearLayout.onLayout(LinearLayout.java:1569) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:325) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at com.android.internal.policy.DecorView.onLayout(DecorView.java:888) at android.view.View.layout(View.java:19781) at android.view.ViewGroup.layout(ViewGroup.java:6144) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2681) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2384) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1522) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7292) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:981) at android.view.Choreographer.doCallbacks(Choreographer.java:790) at android.view.Choreographer.doFrame(Choreographer.java:721) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:967) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7529) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

strangel3t commented 3 years ago

Same on a Nexus 5 yesterday on 2.0.0

laim2003 commented 3 years ago

Same on Samsung Galaxy S20

idanatz commented 3 years ago

v2.1.0 is out with different diffing mechanism implementation, hoping it will solve this bug for good. 🤞 please note that the dependency has changed as well due to the deprecation of the current publication, so take a look at the README.

lrnrzg commented 8 months ago

I reproduced the bug and it will be fixed in the next version. hopefully will be released tomorrow :)

How did you reproduce and fix it? Could you share it please....

lrnrzg commented 8 months ago

v2.1.0 is out with different diffing mechanism implementation, hoping it will solve this bug for good. 🤞 please note that the dependency has changed as well due to the deprecation of the current publication, so take a look at the README.

How did you solve it? I would really appreciate your advice or suggestions. Thank you so much in advance for your help!