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

onDetachedFromWindow is called twice #95

Open
amoikevin opened this issue Jan 20, 2017 · 13 comments
Open

onDetachedFromWindow is called twice #95

amoikevin opened this issue Jan 20, 2017 · 13 comments

Comments

@amoikevin
Copy link

The method "onDetachedFromWindow" of RenderableView is called twice,this will cause some exceptions.
For example, RecyclerView will throw NullPointerException, for mGapWorker was set to null at the first time.

@iciakky
Copy link

iciakky commented Feb 12, 2017

+1
I have exact the same issue.
For now I explicitly unmount my RenderableViews, so that they won't be detach twice.
BTW this issue is probably related to the #82

@zserge
Copy link
Collaborator

zserge commented Feb 13, 2017

Could you please give a bit more context? Are these renderable views located inside other renderable views? Or maybe they are adapter items? Or are they mounted directly into the activity?

FYI, in the upcoming Anvil 0.5.0 (see forge branch for now) I'm hoping to add umount(View v, boolean removeChildViews) to allow unounting RenderableViews without destroying the view hierarchy. Might help in some cases when Android removes child views by itself and doesn't expect Anvil to do so.

@iciakky
Copy link

iciakky commented Feb 13, 2017

For the stack trace, please see the first reply of #82, I've seen it before.
To reproduce this issue, launch this(gist) and tap the back key to exit this app, then comes the NPE:
(the anvil version I'm using is 0.4.0)

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.GapWorker.remove(android.support.v7.widget.RecyclerView)' on a null object reference
                      at android.support.v7.widget.RecyclerView.onDetachedFromWindow(RecyclerView.java:2489)
                      at android.view.View.dispatchDetachedFromWindow(View.java:15560)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3187)
                      at android.view.ViewGroup.removeViewsInternal(ViewGroup.java:4825)
                      at android.view.ViewGroup.removeViews(ViewGroup.java:4681)
                      at trikita.anvil.Anvil.unmount(Anvil.java:138)
                      at trikita.anvil.RenderableView.onDetachedFromWindow(RenderableView.java:33)
                      at android.view.View.dispatchDetachedFromWindow(View.java:15560)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3187)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3179)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3179)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3179)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3179)
                      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3179)
                      at android.view.ViewRootImpl.dispatchDetachedFromWindow(ViewRootImpl.java:3259)
                      at android.view.ViewRootImpl.doDie(ViewRootImpl.java:5917)
                      at android.view.ViewRootImpl.die(ViewRootImpl.java:5894)
                      at android.view.WindowManagerGlobal.removeViewLocked(WindowManagerGlobal.java:446)
                      at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:384)
                      at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:124)
                      at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4243)
                      at android.app.ActivityThread.-wrap6(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1538)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

@FunnyDevs
Copy link

any workaround???

@zserge
Copy link
Collaborator

zserge commented Mar 25, 2017

I'm not sure how this issue has been affected by Anvil 0.5.1, but there is now an option to call Anvil.unmount(view, removeChildViews), so if the issue was caused by the fact that child views has already been removed - then perhaps changing the removeChildViews flag to false in the RenderableView class would help.

@FunnyDevs
Copy link

FunnyDevs commented Mar 25, 2017

The problem comes with recyclerview. The only solution, i think, is create a Custom Renderable View and put "Anvil.unmout(this,false)" inside "onDetachedFromWindow"

@zserge
Copy link
Collaborator

zserge commented Mar 25, 2017

Hm.. So RecyclerView injects some child views on its own, then during the unmount() call we remove its child views and when it tries to do the same - it crashes. I wonder if custom unmount(v, false) works any better, and if so - perhaps unmount() can be rewritten to only remove Anvil own views (much like end() does).

@pardom-zz
Copy link

pardom-zz commented May 28, 2017

I'm getting the same exception as @iciakky

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.GapWorker.remove(android.support.v7.widget.RecyclerView)' on a null object reference
  at android.support.v7.widget.RecyclerView.onDetachedFromWindow(RecyclerView.java:2534)
  at android.view.View.dispatchDetachedFromWindow(View.java:15560)
  at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3187)
  at android.view.ViewGroup.removeViewsInternal(ViewGroup.java:4825)
  at android.view.ViewGroup.removeViews(ViewGroup.java:4681)
  at trikita.anvil.Anvil.unmount(Anvil.java:181)
  at trikita.anvil.Anvil.unmount(Anvil.java:166)
  at trikita.anvil.RenderableView.onDetachedFromWindow(RenderableView.java:33)
  at clean.news.ui.item.list.ItemListView.onDetachedFromWindow(ItemListView.kt:38)
  at android.view.View.dispatchDetachedFromWindow(View.java:15560)
  at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3187)
  at android.view.ViewGroup.removeViewInternal(ViewGroup.java:4715)
  at android.view.ViewGroup.removeViewAt(ViewGroup.java:4665)
  at android.support.v7.widget.RecyclerView$5.removeViewAt(RecyclerView.java:732)
  at android.support.v7.widget.ChildHelper.removeViewAt(ChildHelper.java:168)
  at android.support.v7.widget.RecyclerView$LayoutManager.removeViewAt(RecyclerView.java:7915)
  at android.support.v7.widget.RecyclerView$LayoutManager.removeAndRecycleViewAt(RecyclerView.java:8187)
  at android.support.v7.widget.LinearLayoutManager.recycleChildren(LinearLayoutManager.java:1363)
  at android.support.v7.widget.LinearLayoutManager.recycleViewsFromStart(LinearLayoutManager.java:1409)
  at android.support.v7.widget.LinearLayoutManager.recycleByLayoutState(LinearLayoutManager.java:1478)
  at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1502)
  at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1325)
  at android.support.v7.widget.LinearLayoutManager.scrollHorizontallyBy(LinearLayoutManager.java:1049)
  at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4722)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
  at android.view.Choreographer.doCallbacks(Choreographer.java:686)
  at android.view.Choreographer.doFrame(Choreographer.java:618)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6119)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

I'm rewriting my best practices/example app to use Anvil instead of RxBinding and this is blocking me.

@autonomousapps
Copy link

See this bug report filed on the Android issue tracker: https://issuetracker.google.com/issues/38375597

If you star it, maybe it'll get more attention and get fixed.

@chriscoderdr
Copy link

In my case I could fix it without modifying the recyclerview or downgrading the version
I have my recyclerview inside a custom compound view and I was doing
inflater.inflate(R.layout.layout_name, this, true);
in the constructor now instead of doing it I'm inflating it this way
mView = inflater.infltate(R.layout.layout_name, this, false);
and after that adding the view with
this.addView(mView);

and on my onDetachedFromWindow I have this:

if (mView != null) {
            removeView(mView);
        }

It works like a charm.

@meikaiss
Copy link

support-v7:27.1.0 fix this bug

@CK875430315
Copy link

@meikaiss are you sure? it it still void someone said

@CK875430315
Copy link

@meikaiss i am sry,recyclerview27.1.0 fixed the mGapWorker is null

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

No branches or pull requests

9 participants