在片段中使用LifeCyclescope为什么在ViewPager2中使用时会导致内存泄漏?

发布于 2025-01-22 16:52:31 字数 8962 浏览 2 评论 0原文

我有一个带有View Pager的屏幕,我使用的是同一片段类别的多个片段实例,这些片段类别使用页面3来从服务器加载数据。

在OnViewCreated Inside我具有此功能,

onViewCreated() {
   fun updateList()
}

fun updateList() {
       lifecycleScope.launch {
            viewModel.orders.collectLatest {
                adapter?.submitData(it)
            }
        }
}

上述功能使我有一个内存泄漏,找不到解决方案,并尝试了一下,并且可以使用。仍然找不到为什么它有效的原因,或者这是否是这样做的右路。

viewLifecycleOwner.lifecycleScope.launch {
            viewModel.orders.collectLatest {
                adapter?.submitData(it)
            }
}

泄漏logcat跟踪:

D/LeakCanary: ​
D/LeakCanary: ┬───
D/LeakCanary: │ GC Root: Input or output parameters in native code
D/LeakCanary: │
D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
D/LeakCanary: │    Leaking: NO (InternalLeakCanary↓ is not leaking and A ClassLoader is never leaking)
D/LeakCanary: │    ↓ ClassLoader.runtimeInternalObjects
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary: │    Leaking: NO (InternalLeakCanary↓ is not leaking)
D/LeakCanary: │    ↓ Object[950]
D/LeakCanary: ├─ leakcanary.internal.InternalLeakCanary class
D/LeakCanary: │    Leaking: NO (HomeActivity↓ is not leaking and a class is never leaking)
D/LeakCanary: │    ↓ static InternalLeakCanary.resumedActivity
D/LeakCanary: ├─ com.awantunai.app.home.HomeActivity instance
D/LeakCanary: │    Leaking: NO (Activity#mDestroyed is false)
D/LeakCanary: │    mApplication instance of com.awantunai.app.base.AwanApplication
D/LeakCanary: │    mBase instance of androidx.appcompat.view.ContextThemeWrapper
D/LeakCanary: │    ↓ ComponentActivity.mActivityResultRegistry
D/LeakCanary: │                        ~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.activity.ComponentActivity$2 instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 348,5 kB in 8676 objects
D/LeakCanary: │    Anonymous subclass of androidx.activity.result.ActivityResultRegistry
D/LeakCanary: │    this$0 instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ ActivityResultRegistry.mKeyToLifecycleContainers
D/LeakCanary: │                             ~~~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ java.util.HashMap instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 504 B in 18 objects
D/LeakCanary: │    ↓ HashMap["fragment_978a66c7-ff9d-435c-a477-d49cb3df918d_rq#0"]
D/LeakCanary: │             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.activity.result.ActivityResultRegistry$LifecycleContainer instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 76 B in 3 objects
D/LeakCanary: │    ↓ ActivityResultRegistry$LifecycleContainer.mLifecycle
D/LeakCanary: │                                                ~~~~~~~~~~
D/LeakCanary: ├─ androidx.lifecycle.LifecycleRegistry instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 84,5 kB in 2074 objects
D/LeakCanary: │    ↓ Lifecycle.mInternalScopeRef
D/LeakCanary: │                ~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ java.util.concurrent.atomic.AtomicReference instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 12 B in 1 objects
D/LeakCanary: │    ↓ AtomicReference.value
D/LeakCanary: │                      ~~~~~
D/LeakCanary: ├─ androidx.lifecycle.LifecycleCoroutineScopeImpl instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2042 objects
D/LeakCanary: │    ↓ LifecycleCoroutineScopeImpl.coroutineContext
D/LeakCanary: │                                  ~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ kotlin.coroutines.CombinedContext instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2041 objects
D/LeakCanary: │    ↓ CombinedContext.left
D/LeakCanary: │                      ~~~~
D/LeakCanary: ├─ kotlinx.coroutines.SupervisorJobImpl instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2040 objects
D/LeakCanary: │    ↓ JobSupport._state
D/LeakCanary: │                 ~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.ChildHandleNode instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2039 objects
D/LeakCanary: │    ↓ ChildHandleNode.childJob
D/LeakCanary: │                      ~~~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.StandaloneCoroutine instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2038 objects
D/LeakCanary: │    ↓ JobSupport._state
D/LeakCanary: │                 ~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.ChildHandleNode instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2036 objects
D/LeakCanary: │    ↓ ChildHandleNode.childJob
D/LeakCanary: │                      ~~~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.internal.ScopeCoroutine instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2035 objects
D/LeakCanary: │    ↓ ScopeCoroutine.uCont
D/LeakCanary: │                     ~~~~~
D/LeakCanary: ├─ com.awantunai.app.home.cart.v3.OrderListFragment$updateAdapter$1 instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,6 kB in 1246 objects
D/LeakCanary: │    Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
D/LeakCanary: │    ↓ OrderListFragment$updateAdapter$1.$adapter
D/LeakCanary: │                                        ~~~~~~~~
D/LeakCanary: ├─ com.awantunai.app.home.cart.v3.OrderAdapter instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,6 kB in 1244 objects
D/LeakCanary: │    ↓ RecyclerView$Adapter.mObservable
D/LeakCanary: │                           ~~~~~~~~~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView$AdapterDataObservable instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,0 kB in 1218 objects
D/LeakCanary: │    ↓ Observable.mObservers
D/LeakCanary: │                 ~~~~~~~~~~
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1217 objects
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: │               ~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1215 objects
D/LeakCanary: │    ↓ RecyclerView$RecyclerViewDataObserver.this$0
D/LeakCanary: │                                            ~~~~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1214 objects
D/LeakCanary: │    View not part of a window view hierarchy
D/LeakCanary: │    View.mAttachInfo is null (view detached)
D/LeakCanary: │    View.mID = R.id.rv_orders
D/LeakCanary: │    View.mWindowAttachCount = 1
D/LeakCanary: │    mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ View.mParent
D/LeakCanary: │           ~~~~~~~
D/LeakCanary: ├─ androidx.swiperefreshlayout.widget.SwipeRefreshLayout instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 57,2 kB in 1113 objects
D/LeakCanary: │    View not part of a window view hierarchy
D/LeakCanary: │    View.mAttachInfo is null (view detached)
D/LeakCanary: │    View.mID = R.id.swipe_to_refresh
D/LeakCanary: │    View.mWindowAttachCount = 1
D/LeakCanary: │    mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ View.mParent
D/LeakCanary: │           ~~~~~~~
D/LeakCanary: ╰→ androidx.coordinatorlayout.widget.CoordinatorLayout instance
D/LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because com.awantunai.app.home.cart.v3.OrderListFragment received
D/LeakCanary: ​     Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
D/LeakCanary: ​     Retaining 52,8 kB in 1015 objects
D/LeakCanary: ​     key = 80c7cbe8-db9d-49d9-8607-03f6b9e662bc
D/LeakCanary: ​     watchDurationMillis = 5964
D/LeakCanary: ​     retainedDurationMillis = 949
D/LeakCanary: ​     View not part of a window view hierarchy
D/LeakCanary: ​     View.mAttachInfo is null (view detached)
D/LeakCanary: ​     View.mID = R.id.parentLayout
D/LeakCanary: ​     View.mWindowAttachCount = 1
D/LeakCanary: ​     mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: 
D/LeakCanary: METADATA
D/LeakCanary: 
D/LeakCanary: Build.VERSION.SDK_INT: 32
D/LeakCanary: Build.MANUFACTURER: Google
D/LeakCanary: LeakCanary version: 2.8.1
D/LeakCanary: App process name: com.awantunai.app.alpha
D/LeakCanary: Stats: LruCache[maxSize=3000,hits=134631,misses=245082,hitRate=35%]
D/LeakCanary: RandomAccess[bytes=14017705,reads=245082,travel=175631031479,range=69026744,size=98758092]
D/LeakCanary: Analysis duration: 25897 ms

I have a screen with a view pager inside which I am using multiple fragment instances of same fragment class which are using Paging 3 to load data from server.

Inside onViewCreated I have this function,

onViewCreated() {
   fun updateList()
}

fun updateList() {
       lifecycleScope.launch {
            viewModel.orders.collectLatest {
                adapter?.submitData(it)
            }
        }
}

The above function was giving me a memory leak, couldn't find a solution and gave this a try and it worked. Still not able to find why it worked or whether this is the rightway to do it.

viewLifecycleOwner.lifecycleScope.launch {
            viewModel.orders.collectLatest {
                adapter?.submitData(it)
            }
}

Leak Logcat trace:

D/LeakCanary: ​
D/LeakCanary: ┬───
D/LeakCanary: │ GC Root: Input or output parameters in native code
D/LeakCanary: │
D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
D/LeakCanary: │    Leaking: NO (InternalLeakCanary↓ is not leaking and A ClassLoader is never leaking)
D/LeakCanary: │    ↓ ClassLoader.runtimeInternalObjects
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary: │    Leaking: NO (InternalLeakCanary↓ is not leaking)
D/LeakCanary: │    ↓ Object[950]
D/LeakCanary: ├─ leakcanary.internal.InternalLeakCanary class
D/LeakCanary: │    Leaking: NO (HomeActivity↓ is not leaking and a class is never leaking)
D/LeakCanary: │    ↓ static InternalLeakCanary.resumedActivity
D/LeakCanary: ├─ com.awantunai.app.home.HomeActivity instance
D/LeakCanary: │    Leaking: NO (Activity#mDestroyed is false)
D/LeakCanary: │    mApplication instance of com.awantunai.app.base.AwanApplication
D/LeakCanary: │    mBase instance of androidx.appcompat.view.ContextThemeWrapper
D/LeakCanary: │    ↓ ComponentActivity.mActivityResultRegistry
D/LeakCanary: │                        ~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.activity.ComponentActivity$2 instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 348,5 kB in 8676 objects
D/LeakCanary: │    Anonymous subclass of androidx.activity.result.ActivityResultRegistry
D/LeakCanary: │    this$0 instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ ActivityResultRegistry.mKeyToLifecycleContainers
D/LeakCanary: │                             ~~~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ java.util.HashMap instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 504 B in 18 objects
D/LeakCanary: │    ↓ HashMap["fragment_978a66c7-ff9d-435c-a477-d49cb3df918d_rq#0"]
D/LeakCanary: │             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.activity.result.ActivityResultRegistry$LifecycleContainer instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 76 B in 3 objects
D/LeakCanary: │    ↓ ActivityResultRegistry$LifecycleContainer.mLifecycle
D/LeakCanary: │                                                ~~~~~~~~~~
D/LeakCanary: ├─ androidx.lifecycle.LifecycleRegistry instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 84,5 kB in 2074 objects
D/LeakCanary: │    ↓ Lifecycle.mInternalScopeRef
D/LeakCanary: │                ~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ java.util.concurrent.atomic.AtomicReference instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 12 B in 1 objects
D/LeakCanary: │    ↓ AtomicReference.value
D/LeakCanary: │                      ~~~~~
D/LeakCanary: ├─ androidx.lifecycle.LifecycleCoroutineScopeImpl instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2042 objects
D/LeakCanary: │    ↓ LifecycleCoroutineScopeImpl.coroutineContext
D/LeakCanary: │                                  ~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ kotlin.coroutines.CombinedContext instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2041 objects
D/LeakCanary: │    ↓ CombinedContext.left
D/LeakCanary: │                      ~~~~
D/LeakCanary: ├─ kotlinx.coroutines.SupervisorJobImpl instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2040 objects
D/LeakCanary: │    ↓ JobSupport._state
D/LeakCanary: │                 ~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.ChildHandleNode instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,7 kB in 2039 objects
D/LeakCanary: │    ↓ ChildHandleNode.childJob
D/LeakCanary: │                      ~~~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.StandaloneCoroutine instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2038 objects
D/LeakCanary: │    ↓ JobSupport._state
D/LeakCanary: │                 ~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.ChildHandleNode instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2036 objects
D/LeakCanary: │    ↓ ChildHandleNode.childJob
D/LeakCanary: │                      ~~~~~~~~
D/LeakCanary: ├─ kotlinx.coroutines.internal.ScopeCoroutine instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 83,6 kB in 2035 objects
D/LeakCanary: │    ↓ ScopeCoroutine.uCont
D/LeakCanary: │                     ~~~~~
D/LeakCanary: ├─ com.awantunai.app.home.cart.v3.OrderListFragment$updateAdapter$1 instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,6 kB in 1246 objects
D/LeakCanary: │    Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
D/LeakCanary: │    ↓ OrderListFragment$updateAdapter$1.$adapter
D/LeakCanary: │                                        ~~~~~~~~
D/LeakCanary: ├─ com.awantunai.app.home.cart.v3.OrderAdapter instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,6 kB in 1244 objects
D/LeakCanary: │    ↓ RecyclerView$Adapter.mObservable
D/LeakCanary: │                           ~~~~~~~~~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView$AdapterDataObservable instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 61,0 kB in 1218 objects
D/LeakCanary: │    ↓ Observable.mObservers
D/LeakCanary: │                 ~~~~~~~~~~
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1217 objects
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: │               ~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1215 objects
D/LeakCanary: │    ↓ RecyclerView$RecyclerViewDataObserver.this$0
D/LeakCanary: │                                            ~~~~~~
D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 60,9 kB in 1214 objects
D/LeakCanary: │    View not part of a window view hierarchy
D/LeakCanary: │    View.mAttachInfo is null (view detached)
D/LeakCanary: │    View.mID = R.id.rv_orders
D/LeakCanary: │    View.mWindowAttachCount = 1
D/LeakCanary: │    mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ View.mParent
D/LeakCanary: │           ~~~~~~~
D/LeakCanary: ├─ androidx.swiperefreshlayout.widget.SwipeRefreshLayout instance
D/LeakCanary: │    Leaking: UNKNOWN
D/LeakCanary: │    Retaining 57,2 kB in 1113 objects
D/LeakCanary: │    View not part of a window view hierarchy
D/LeakCanary: │    View.mAttachInfo is null (view detached)
D/LeakCanary: │    View.mID = R.id.swipe_to_refresh
D/LeakCanary: │    View.mWindowAttachCount = 1
D/LeakCanary: │    mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: │    ↓ View.mParent
D/LeakCanary: │           ~~~~~~~
D/LeakCanary: ╰→ androidx.coordinatorlayout.widget.CoordinatorLayout instance
D/LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because com.awantunai.app.home.cart.v3.OrderListFragment received
D/LeakCanary: ​     Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
D/LeakCanary: ​     Retaining 52,8 kB in 1015 objects
D/LeakCanary: ​     key = 80c7cbe8-db9d-49d9-8607-03f6b9e662bc
D/LeakCanary: ​     watchDurationMillis = 5964
D/LeakCanary: ​     retainedDurationMillis = 949
D/LeakCanary: ​     View not part of a window view hierarchy
D/LeakCanary: ​     View.mAttachInfo is null (view detached)
D/LeakCanary: ​     View.mID = R.id.parentLayout
D/LeakCanary: ​     View.mWindowAttachCount = 1
D/LeakCanary: ​     mContext instance of com.awantunai.app.home.HomeActivity with mDestroyed = false
D/LeakCanary: 
D/LeakCanary: METADATA
D/LeakCanary: 
D/LeakCanary: Build.VERSION.SDK_INT: 32
D/LeakCanary: Build.MANUFACTURER: Google
D/LeakCanary: LeakCanary version: 2.8.1
D/LeakCanary: App process name: com.awantunai.app.alpha
D/LeakCanary: Stats: LruCache[maxSize=3000,hits=134631,misses=245082,hitRate=35%]
D/LeakCanary: RandomAccess[bytes=14017705,reads=245082,travel=175631031479,range=69026744,size=98758092]
D/LeakCanary: Analysis duration: 25897 ms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

活泼老夫 2025-01-29 16:52:31

做了一些研究,并意识到ViewLifeCycleOwner.LifeCyclesCope必然从OnCreateview到Ondestroyview开始生命周期。

另一方面,如果我们只使用此。LifeCycleScope,则该范围将从Onattach到OnDetach开始。

在上面的表达式中,假设当我移动到另一个片段时,视图被破坏了,此后在此之前,在拨打ondetach之前,我会在响应中响应

viewModel.orders.collectLatest {
adapter?.submitData(it)
}

片段的视图时会访问recyclerview,因为片段的视图被破坏了,因为它保留了适配器,并导致内存泄漏

在这里一些参考:
https://cs-ibrahimyilmaz.medium.com/viewlifecycleowner-vs-this- A8259800367B

Did some research and realized that viewLifeCycleOwner.lifecycleScope is bound to lifecycle starting from onCreateView to onDestroyView.

On the other hand, if we use just use this.lifecycleScope, this scope will be bound starting from onAttach to onDetach.

In the above expression, let's say the view got destroyed when i moved to the other fragment and after this before calling onDetach i get response in

viewModel.orders.collectLatest {
adapter?.submitData(it)
}

This will access recyclerview when fragment's view is destroyed because its holding reference to adapter and cause a memory leak

Here is some reference:
https://cs-ibrahimyilmaz.medium.com/viewlifecycleowner-vs-this-a8259800367b

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文