Code: Select all
@HiltViewModel
class DocPageListViewModel @Inject constructor(
private val docPageDao: DocPageDao,
) : BaseViewModel() {
val pageModelPagingDataFlow = Pager(PagingConfig(pageSize = 10, initialLoadSize = 20)) {
docPageDao.getPagingSource()
}.flow.cachedIn(viewModelScope)
}
< /code>
@Dao
interface DocPageDao {
@Query("""
SELECT rowid, lid, `key`
FROM page_table_fts4
ORDER BY `key`
""")
fun getPagingSource(): PagingSource
}
< /code>
@AndroidEntryPoint
class DocPageListFragment : BaseFragment(
R.layout.fragment_doc_page_list
) {
override val viewModel: DocPageListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val listAdapter = DocPageListPagingDataAdapter(requireContext(), this)
binding.recyclerView.adapter = listAdapter
viewCollectLatestWhenStarted(viewModel.pageModelPagingDataFlow) { pagingData ->
listAdapter.submitData(pagingData)
}
}
}
< /code>
fun Fragment.viewCollectLatestWhenStarted(flow: Flow, block: suspend (T) -> Unit) {
viewCollectLatestWhen(Lifecycle.State.STARTED, flow, block)
}
fun Fragment.viewCollectLatestWhen(state: Lifecycle.State, flow: Flow, block: suspend (T) -> Unit) {
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(state) {
flow.collectLatest {
block(it)
}
}
}
}
< /code>
┬───
│ GC Root: System class
│
├─ android.provider.FontsContract class
│ Leaking: NO (App↓ is not leaking and a class is never leaking)
│ ↓ static FontsContract.sContext
├─ com.example.name.App instance
│ Leaking: NO (Application is a singleton)
│ mBase instance of android.app.ContextImpl
│ ↓ Hilt_App.componentManager
│ ~~~~~~~~~~~~~~~~
├─ dagger.hilt.android.internal.managers.ApplicationComponentManager instance
│ Leaking: UNKNOWN
│ Retaining 40 B in 3 objects
│ ↓ ApplicationComponentManager.component
│ ~~~~~~~~~
├─ com.example.name.DaggerApp_HiltComponents_SingletonC$SingletonCImpl instance
│ Leaking: UNKNOWN
│ Retaining 25,5 kB in 999 objects
│ ↓ DaggerApp_HiltComponents_SingletonC$SingletonCImpl.provideDatabaseProvider6
│ ~~~~~~~~~~~~~~~~~~~~~~~~
├─ dagger.internal.DoubleCheck instance
│ Leaking: UNKNOWN
│ Retaining 16 B in 1 objects
│ ↓ DoubleCheck.instance
│ ~~~~~~~~
├─ com.example.name.db.docs.DocsDatabase_Impl instance
│ Leaking: UNKNOWN
│ Retaining 14,9 kB in 540 objects
│ ↓ RoomDatabase.transactionContext
│ ~~~~~~~~~~~~~~~~~~
├─ kotlin.coroutines.CombinedContext instance
│ Leaking: UNKNOWN
│ Retaining 32 B in 2 objects
│ ↓ CombinedContext.left
│ ~~~~
├─ kotlinx.coroutines.SupervisorJobImpl instance
│ Leaking: UNKNOWN
│ Retaining 105 B in 5 objects
│ ↓ JobSupport._state$volatile
│ ~~~~~~~~~~~~~~~
├─ kotlinx.coroutines.NodeList instance
│ Leaking: UNKNOWN
│ Retaining 88 B in 4 objects
│ ↓ LockFreeLinkedListNode._prev$volatile
│ ~~~~~~~~~~~~~~
├─ kotlinx.coroutines.ChildHandleNode instance
│ Leaking: UNKNOWN
│ Retaining 28 B in 1 objects
│ ↓ ChildHandleNode.childJob
│ ~~~~~~~~
├─ kotlinx.coroutines.StandaloneCoroutine instance
│ Leaking: UNKNOWN
│ Retaining 20 B in 1 objects
│ ↓ JobSupport._state$volatile
│ ~~~~~~~~~~~~~~~
├─ kotlinx.coroutines.ChildContinuation instance
│ Leaking: UNKNOWN
│ Retaining 28 B in 1 objects
│ ↓ ChildContinuation.child
│ ~~~~~
├─ kotlinx.coroutines.CancellableContinuationImpl instance
│ Leaking: UNKNOWN
│ Retaining 10,5 kB in 355 objects
│ ↓ CancellableContinuationImpl.delegate
│ ~~~~~~~~
├─ kotlinx.coroutines.internal.DispatchedContinuation instance
│ Leaking: UNKNOWN
│ Retaining 10,4 kB in 354 objects
│ ↓ DispatchedContinuation.continuation
│ ~~~~~~~~~~~~
├─ kotlinx.coroutines.flow.StateFlowImpl$collect$1 instance
│ Leaking: UNKNOWN
│ Retaining 10,4 kB in 353 objects
│ Anonymous subclass of kotlin.coroutines.jvm.internal.ContinuationImpl
│ ↓ StateFlowImpl$collect$1.L$1
│ ~~~
├─ androidx.room.TriggerBasedInvalidationTracker$createFlow$1$2 instance
│ Leaking: UNKNOWN
│ Retaining 37 B in 2 objects
│ Anonymous class implementing kotlinx.coroutines.flow.FlowCollector
│ ↓ TriggerBasedInvalidationTracker$createFlow$1$2.$$this$flow
│ ~~~~~~~~~~~
├─ kotlinx.coroutines.flow.internal.SafeCollector instance
│ Leaking: UNKNOWN
│ Retaining 52 B in 2 objects
│ ↓ SafeCollector.collector
│ ~~~~~~~~~
├─ androidx.room.paging.CommonLimitOffsetImpl$load$2$1 instance
│ Leaking: UNKNOWN
│ Retaining 12 B in 1 objects
│ Anonymous class implementing kotlinx.coroutines.flow.FlowCollector
│ ↓ CommonLimitOffsetImpl$load$2$1.this$0
│ ~~~~~~
├─ androidx.room.paging.CommonLimitOffsetImpl instance
│ Leaking: UNKNOWN
│ Retaining 10,0 kB in 339 objects
│ ↓ CommonLimitOffsetImpl.pagingSource
│ ~~~~~~~~~~~~
├─ com.example.name.db.docs.dao.DocPageDao_Impl$3 instance
│ Leaking: UNKNOWN
│ Retaining 9,8 kB in 331 objects
│ Anonymous subclass of androidx.room.paging.LimitOffsetPagingSource
│ ↓ PagingSource.invalidateCallbackTracker
│ ~~~~~~~~~~~~~~~~~~~~~~~~~
├─ androidx.paging.InvalidateCallbackTracker instance
│ Leaking: UNKNOWN
│ Retaining 9,8 kB in 330 objects
│ ↓ InvalidateCallbackTracker.callbacks
│ ~~~~~~~~~
├─ java.util.ArrayList instance
│ Leaking: UNKNOWN
│ Retaining 9,7 kB in 327 objects
│ ↓ ArrayList[1]
│ ~~~
├─ androidx.paging.PageFetcher$generateNewPagingSource$3 instance
│ Leaking: UNKNOWN
│ Retaining 9,7 kB in 324 objects
│ Anonymous subclass of kotlin.jvm.internal.FunctionReferenceImpl
│ ↓ CallableReference.receiver
│ ~~~~~~~~
├─ androidx.paging.PageFetcher instance
│ Leaking: UNKNOWN
│ Retaining 9,6 kB in 323 objects
│ ↓ PageFetcher.pagingSourceFactory
│ ~~~~~~~~~~~~~~~~~~~
├─ androidx.paging.Pager$flow$2 instance
│ Leaking: UNKNOWN
│ Retaining 9,2 kB in 301 objects
│ Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
│ ↓ Pager$flow$2.$pagingSourceFactory
│ ~~~~~~~~~~~~~~~~~~~~
├─ com.example.name.screens.docs.DocPageListViewModel$$ExternalSyntheticLambda0 instance
│ Leaking: UNKNOWN
│ Retaining 9,2 kB in 300 objects
│ ↓ DocPageListViewModel$$ExternalSyntheticLambda0.f$0
│ ~~~
╰→ com.example.name.screens.docs.DocPageListViewModel instance
Leaking: YES (ObjectWatcher was watching this because com.example.name.screens.docs.DocPageListViewModel
received ViewModel#onCleared() callback)
Retaining 9,2 kB in 299 objects
key = 960c859b-f116-4150-842c-39fc5e2fc4d1
watchDurationMillis = 12664
retainedDurationMillis = 7664