Status Update
Comments
wa...@gmail.com <wa...@gmail.com> #2
My MainActivity
extends BaseBindingActivity
with generic argument MainActivityBinding
:
@AndroidEntryPoint
class MainActivity : BaseBindingActivity<MainActivityBinding>()
binding
instantiated by inflateBinding
extension in BaseBindingActivity
:
abstract class BaseBindingActivity<VB : ViewDataBinding> : BaseThemeActivity(), IBinding<VB> {
override lateinit var binding: VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = (inflateBinding(layoutInflater) as VB).also {
it.lifecycleOwner = this
setContentView(it.root)
}
}
}
inflateBinding
generate binding by reflection:
fun <T : ViewBinding> LifecycleOwner.inflateBinding(inflater: LayoutInflater): T {
return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments
.filterIsInstance<Class<T>>()
.first()
.getDeclaredMethod("inflate", LayoutInflater::class.java)
.invoke(null, inflater) as T
}
wa...@gmail.com <wa...@gmail.com> #3
mk...@google.com <mk...@google.com> #4
Thank you for the report. R8 fullmode will remove the generic signature of classes and methods that are is not directly kept - both on the class that has the generic parameters on that class that instantiates them. But from your example I would have thought that BaseBindingActivity would have been kept since it derives from AppCompatActivity. But perhaps there is no keep rule generated by that automatically?
In any case, see if -keep,allowshrinking class * extends BaseBindingActivity
will solve your issue. If not, could you share a dump of your input by running:
./gradlew assembleRelease -Dcom.android.tools.r8.dumpinputtodirectory=/path/to/dumps --no-daemon
You can share by sending to
wa...@gmail.com <wa...@gmail.com> #5
Doesn't work. I've sent dumps to you.
mk...@google.com <mk...@google.com> #6
OK, so BaseBindingActivity is not kept (which is also clear from it being minified). Since it is not kept, the generic signature of BaseBindingActivity is removed and to recover from that the generic signature on MainActivity is rewritten to to a super type that do not pass in any generic signature arguments - it is not removed it just no longer have a type argument to the super class.
The fix is therefore just to add a -keep class BaseBindingActivity
. I believe -keep,allowobfuscation class BaseBindingActivity
should also work.
wa...@gmail.com <wa...@gmail.com> #7
Both -keep class io.goooler.demoapp.common.base.binding.BaseBindingActivity
and -keep,allowobfuscation class io.goooler.demoapp.common.base.binding.BaseBindingActivity
are not working.
mk...@google.com <mk...@google.com> #8
Alright, I know why. In your example you write this as the input
class MainActivity : BaseBindingActivity<MainActivityBinding>()
and the following as the output.
public final class MainActivity extends a
I assumed a
was BaseBindingActivity<MainActivityBinding>()
. IT IS NOT :)
You have some reflection going on (HILT?) that injects a class in between MainActivity
and BaseBindingActivity
. So the class is actually:
Class: io.goooler.demoapp.main.ui.MainActivity extends io.goooler.demoapp.main.ui.Hilt_MainActivity
Signature extends BaseBindingActivity<MainActivityBinding>
R8 verifies signatures before continueing and the generic signature is incorrect - it does not match the class hierarchy. R8 therefore emits:
Invalid signature 'Lio/goooler/demoapp/common/base/binding/BaseBindingActivity<Lio/goooler/demoapp/main/databinding/MainActivityBinding;>;' for class io.goooler.demoapp.main.ui.MainActivity.
Validation error: The generic super type is not the same as the class super type.
Signature is ignored and will not be present in the output.
That it worked before is only because there is no validation of generic signatures, but we have to do it, otherwise we cannot rewrite signatures correctly. The fix works, but only if you have a correct generic signature for io.goooler.demoapp.main.ui.MainActivity. I am not sure what the correct fix is here.
The reflection should rewrite the generic signature correctly - otherwise, if you can tailor it, do not rely on generic signatures but use annotations or similar.
wa...@gmail.com <wa...@gmail.com> #9
You are right, I started a new project for a test without Hilt, after adding the proguard rules you suggested, it works.
wa...@gmail.com <wa...@gmail.com> #10
Should R8 fullMode handle this case (using with Hilt or something else)?
mk...@google.com <mk...@google.com> #11
I do not think R8 fullmode should patch generic signatures depending on reflection. I am also unsure how much of the reflection is library and how much is your code. Perhaps ths is dagger issue?
wa...@gmail.com <wa...@gmail.com> #12
wa...@gmail.com <wa...@gmail.com> #13
I noticed after upgrading to AGP 7.1.0 with compatibility mode, the generic signature has also been removed like full mode in AGP 7.0.4 did, is there a behavior change?
mk...@google.com <mk...@google.com> #14
AGP 7.1 has correct rewriting of all generic signature - the only way the rewriting can be correct is if the it is correct on the input. So yes, we now require that the generic signature is correct otherwise we can not realiably rewrite it.
mk...@google.com <mk...@google.com> #16
Assigning to sgjesse@ that is looking closer at HILT and dagger in Android.
mk...@google.com <mk...@google.com> #18
Thanks for filing the bug and reporting back. Will close this bug as WAI.
fc...@gmail.com <fc...@gmail.com> #19
mk...@google.com <mk...@google.com> #20
This is marked as intended behavior so this is not an error in R8. I would not what version of dagger to use but you should check on the filed bugs with dagger.
wa...@gmail.com <wa...@gmail.com> #21
It had been fixed in Dagger/Hilt, you can just use the latest Dagger/Hilt.
Description