Status Update
Comments
ch...@google.com <ch...@google.com> #2
This sounds like a duplicate of
vi...@gmail.com <vi...@gmail.com> #3
Thank you for the linked issue, the comments there were very helpful. It does look like issues are related. My apologies for creating a duplicate issue
Description
R8: 8.1.68 (also tried 8.1.73)
I'm facing a strange issue in my project that uses WeakReferences I think might be related to R8 as the bug is only present when building in release or with R8 enabled.
Simplified, I have an object(Singleton) that contains a list of listeners, which are WeakReferences to lambdas. Then I have class (Observer) which contain the lambda that gets registered to the Singleton. Because Singleton will outline this class, lambdas are added as a WeakReference. Singleton then uses this listeners to notify them of an update. I've attached a simple project demonstrating this
What I've noticed is that, on AGP 8.1, after some time (10s or so) the WeakReferences will be become null as if they were cleared, even though the class whose lambda was registered is still alive. Since this only happens when building with R8 enabled I suspected something with minification/obfuscation might cause this. If I add @Keep annotation to the 2 classes (or adding a proguard rule) then the bug is not present anymore.
I've also looked at the decompiled sources of the app with and without the @Keep annotation and saw that with @Keep annotation the listeners get added in a different way then without the @Keep annotation. Not sure what might cause that or if that is causing the issue. It looks like, without @Keep annotation lambdas with same signature get bundled together into a single class, vs with @Keep annotation the lambda is a separate class
In a different project, using the same setup but with AGP 7.4 the bug is not present.
Steps to reproduce in the sample project
1.) Make sure you release mode is selected and the @Keep annotation/proguard rules are not added
2.) Open the app
3.) Click on the button
A console log should output something like
Singleton notify references with key:2 all references:[java.lang.ref.WeakReference@1cbece7]
Singleton notify next lambda:interface o2.c
4.) Wait for a few seconds
5.) Press the button again
Then, the output will change to something like
Singleton notify references with key:2 all references:[java.lang.ref.WeakReference@1cbece7]
Singleton notify next null
Note, it might take a few tries of steps 4 and 5 before its reproducible
For now, I can fix this by adding @Keep annotation or proguard rules, but would like to understand what might be the cause of this as potentially this could affect other parts of the app that use WeakReferences. Any advice/guidance is appreciated