18

I believe that onAttachedToWindow() is called when the onCreate()'s setContentView(R.layout.myLayout.xml) is called. So can I assume then that in the activity lifecycle that onDetachedFromWindow() is called when the activity is destroyed? My question is how do I tie these two call back hooks to the activities lifecycle?

Can I say that onAttachedToWindow() is tied to onCreate() and onDetachedFromWindow() is tied to onDestroy()?

0xCursor
  • 2,242
  • 4
  • 15
  • 33
j2emanue
  • 60,549
  • 65
  • 286
  • 456

3 Answers3

22

Technically speaking onAttachedToWindow is called after onResume(and it happens only once perlifecycle). ActivityThread.handleResumeActivity call will add DecorView to the current WindowManger which will in turn call WindowManagerGlobal.addView() which than traverse all the views and call onAttachedToWindow on each view.

onDetachedFromWindow is tied with onDestroy

WenChao
  • 3,586
  • 6
  • 32
  • 46
  • question. if its called in onResume then that means everytime the activity resumes the view re - attaches again to the activity ? – j2emanue Feb 09 '17 at 03:03
  • @WenChao That's not true. onAttachedToWindow is called only ONCE per the lifetime of that particular activity. – Catalin Morosan Mar 29 '17 at 11:14
  • 1
    @CatalinMorosan, I should state it more clear, you are correct it is called ONCE per lifetime. What I was trying to say is the first(and only) `onAttachedToWindow` happens after `onResume`, there is no more call to `onAttachedToWindow` afterwards in the lifecycle. Thanks. – WenChao Mar 30 '17 at 00:18
  • 1
    @j2emanue I have updated my answer, Views are not re-attached when activity is resumed – WenChao Mar 30 '17 at 00:31
  • onAttachedToWindow can be called more than once if the view is being used by a RecyclerView. – enl8enmentnow Oct 24 '22 at 17:23
6

This is not really an answer but an advice ...

Many times, I've felt the urge to use this method (onDetachedFromWindow) to unregister observers and/or clear scopes...

DO NOT DO THIS!!

onDetachedFromWindow() does not equal Fragment's onDestroyView().

There is no inner method that gets called specifically when the view is destroyed (unfortunately).

onDetachFromWindow() will get called when changing the page in a ViewPager/ViewPager2, while the view is not really being destroyed. If you use onDetachFromWindow() to clear scopes, you'll either get a NullPointerException, or the view will simply stop responding to updates when scrolling back to the page in question.

The best and easiest thing you could do is use the onDestroyView() method to clear scopes.

The hardest/best way is to listen for the Fragment's LifeCycle (if you want a one time instantiated Adapter), and then dispatch an "destroyed" message through the Adapter to all views observing the Adapter and make them self-unregister themselves.... not even the DataSetObserver class is built to do this (when it should).

Delark
  • 1,141
  • 2
  • 9
  • 15
  • What I've been using is the LifeCycleEventObserver and I still need to manually unregister it on destroy :/, but once the component is fully polished, it becomes extremely scalable. – Delark Dec 10 '20 at 02:34
4

I find it's possible that onAttachedToWindow will be called when setContentView is called.

When you use split screen on Android N, and the value of configChanges of activity in AndroidManifest.xml to be set:

 "keyboardHidden|orientation|screenSize"

onAttachedToWindow will be called in setContentView, because the the variable "mAttachInfo" in the decorview of window is not null, when you call setContentView to add rootView to decorView, dispatchAttachedToWindow is called in addViewInner().

Finally after activity onResume(), onAttachedToWindow() is not be called again.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Joe Chan
  • 73
  • 5