https://kotlinlang.org logo
#android
Title
# android
f

Fredrik Larsen

03/19/2019, 8:43 PM
If you're wondering why I ask this in a kotlin related channel, it is because I see multiple examples where people use
lazy
or
lateinit
which will retain the instances. The same goes for views, unless you use synthetics which in itself is a bit "hacky" imo.
g

ghedeon

03/19/2019, 8:51 PM
Why would you go an extra mile to mess with adapter instance instead of letting the GC to do its work? It's a field (probably lateinit) in the fragment like many others. It will go, once the fragment is destroyed. Do you face any particular issues with that?
f

Fredrik Larsen

03/19/2019, 8:54 PM
Because the fragment is not destroyed. Only the view. When you navigate and put the fragment in the backstack it's retained. Meaning GC will not collect the adapter.
g

ghedeon

03/19/2019, 8:54 PM
yes, that's how it should be
also, adapter doesn't keep views, only items.
f

Fredrik Larsen

03/19/2019, 8:59 PM
So you're saying the recyclerview adapter will not retain the viewholders?
In that case you're right, there is no need to manually release/recreate the adapter.
g

ghedeon

03/19/2019, 8:59 PM
adapter is kind of a viewmodel for the view (recycler). Normally you don't clean the model when the view is destroyed.
Holders are kept in the RecyclerView, not in the adapter.
f

Fredrik Larsen

03/19/2019, 9:00 PM
That's true. Thank you for clearing that up.
😉 1
On a similar note though, If I did not use synthetics but rather
Copy code
lateinit var recyclerView: RecyclerView
then I would be retaining that view even after
onDestroyView()
which in the case with recyclerViews full of images would retain a lot of memory
I didn't phrase that as a question, but I do wonder how other deal with that use case.
Apart from the obvious - making it nullable and setting it to null in
onDestroyView()
.
g

ghedeon

03/19/2019, 10:13 PM
yes, you'd need to set it to null manually. Or call
unbind()
from ButterKnife. Or just use synthetics, it's so simple, I can't see myself going back 😏
s

Sam

03/20/2019, 1:54 AM
@Fredrik Larsen I had similar issues. I don't use members to keep a reference to views anymore https://medium.com/@debuggingisfun/fragments-in-2019-1d9898239ebb
Also, when in doubt, just enable leak canary fragments, that will give you a hint when there is a leak
// Optional, if you use support library fragments: debugImplementation 'com.squareup.leakcanaryleakcanary support fragment1.6.3'
f

Fredrik Larsen

03/20/2019, 9:46 AM
I did some more digging and ViewHolders are retained by the LayoutManager, så destroying the recyclerview doesn't release them. You need to destroy the LayoutManager as well.
In other words if you add a lot of fragments to the backstack (navigation) and you deal with many images, then this essentially a memory leak:
Copy code
private lateinit var layoutManager: RecyclerView.LayoutManager
g

ghedeon

03/20/2019, 10:56 AM
I don't think any of discussed cases qualify as proper leaks, once the fragment is gone it will go as well. But yes, if you keep it in a field then it won't be released onDestroyView. Thus, if you don't nullify your references, you retain views longer than you'd want.
f

Fredrik Larsen

03/20/2019, 12:41 PM
It's nice to be aware of it as memory builds up. But I agree, not a leak per say.