Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash in OrmaListAdapter and OrmaRecyclerViewAdapter on multiple deletions simultaneously #103

Open
gfx opened this issue Jan 3, 2016 · 6 comments
Labels

Comments

@gfx
Copy link
Member

gfx commented Jan 3, 2016

No description provided.

@gfx gfx added the bug label Jan 3, 2016
@gfx gfx added this to the v1.1.0 milestone Jan 3, 2016
@gfx
Copy link
Member Author

gfx commented Jan 13, 2016

ANR is no longer produced in v0.31.0, but NoValueException may occur in the same situation.

@gfx gfx changed the title ANR in TodoActivity when multiple insertions and deletions simultaneously Crash in OrmaListAdapter and OrmaRecyclerViewAdapter when multiple deletions simultaneously Jan 14, 2016
@gfx gfx changed the title Crash in OrmaListAdapter and OrmaRecyclerViewAdapter when multiple deletions simultaneously Crash in OrmaListAdapter and OrmaRecyclerViewAdapter on multiple deletions simultaneously Jan 14, 2016
@gfx gfx modified the milestones: v1.2.0, v1.1.0 Jan 25, 2016
@gfx gfx added the ready label Feb 23, 2016
@gfx gfx changed the title Crash in OrmaListAdapter and OrmaRecyclerViewAdapter on multiple deletions simultaneously Crash in OrmaListAdapter and OrmaRecyclerViewAdapter on multiple deletions simultaneously Jun 14, 2016
@gfx gfx removed the ready label Jun 14, 2016
@karino2
Copy link

karino2 commented Sep 22, 2017

I found similar issue when delete one item (OrmaAdapter sometime cause crash).
Is this the same issue?
My Orma version is 4.2.5.

Note: My issue is hard to reproduce and only happens occasionally. That's why investigation like stabilize reproduce step is difficult.

Here is my stacktrace:

FATAL EXCEPTION: main
Process: karino2.livejournal.com.meatpieday, PID: 11093
com.github.gfx.android.orma.exception.NoValueException: ouf of range: getItem(13) for the relation with 13 items
at com.github.gfx.android.orma.widget.OrmaAdapter.getItem(OrmaAdapter.java:115)
at karino2.livejournal.com.meatpieday.CellListAdapter.getItemId(CellListAdapter.java:35)
at android.widget.AbsListView$RecycleBin.retrieveFromScrap(AbsListView.java:9158)
at android.widget.AbsListView$RecycleBin.getScrapView(AbsListView.java:8886)
at android.widget.AbsListView.obtainView(AbsListView.java:2933)
at android.widget.ListView.makeAndAddView(ListView.java:1945)
at android.widget.ListView.fillDown(ListView.java:719)
at android.widget.ListView.fillSpecific(ListView.java:1391)
at android.widget.ListView.layoutChildren(ListView.java:1712)
at android.widget.AbsListView.onLayout(AbsListView.java:2731)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:3146)
at android.view.View.layout(View.java:17993)
at android.view.ViewGroup.layout(ViewGroup.java:5817)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2755)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2456)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1524)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7520)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:622)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1321)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1211)

@karino2
Copy link

karino2 commented Sep 22, 2017

In normal case, queryObservableSubscription seems called and cache.evictAll() is called.
Is mItemCount of ListView stale?

@karino2
Copy link

karino2 commented Sep 22, 2017

mItemCount should be updated at AdapterDataSetObserver::onChanged().
This is registered at AbsListView and onChanged is called when BaseAdapter::notifyDataSetChanged() is called.
So, it must be updated if OrmaListAdapter::notifyDatasetChanged() called correctly.

Is there some situation following observer is called before OrmaListAdapter::getCount() is not updated?

        delegate.addSubscription(delegate.getQueryObservable()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Selector<Model, ?>>() {
                    @Override
                    public void accept(Selector<Model, ?> selector) throws Exception {
                        notifyDataSetChanged();
                    }
                }));

@karino2
Copy link

karino2 commented Dec 27, 2018

I guess when cell deleter is called, this subscription is not fired just at time and some UI related preemptin occur for fling case.
I guess Delete and notifyDataSetChanged must be atomic.

Add: But notifyDataSetChanged must be called from UI Thread. How to make sure other fling related operation occure before this action?

@karino2
Copy link

karino2 commented Dec 27, 2018

This crash occur when there is a race condition for UI update and cursor deletion.
For example, if user select list item via ContextualActionBar, then choose delete.

`
Completable.fromAction(()-> {
getOrmaDatabase()
.deleteFromCell()
.idIn(ids)
.execute();
}).subscribeOn(Schedulers.io())
.subscribe();

actionMode.finish();
`

In this case, CAB related update occur just the same timing as deletion.
If CAB update cause getItem query before notifyDataSetChanged, but cursor is already updated, this cause crash (out of range access).

Work around is CAB finish call before cursor deletion.
This fix most of the case, but not perfect solution for this.
I don't know how to fix this problem.

Cursor have some observer API for data set(registerDataSetObserver).
CursorAdapter register DataSetObserver to cursor, and call notifyDataSetChanged from this observer.
I'm not fully sure whether this code really fix all the race condition, but I guess orma should handle datasetobserver of cursor someway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants