moxy-community / Moxy

Moxy is MVP library for Android with incremental annotation processor and ktx features
MIT License
324 stars 33 forks source link

R8 full mode removes necessary classes #141

Closed p-dmitriy closed 3 months ago

p-dmitriy commented 11 months ago

Problem

After update to AGP 8+ where R8 full mode enabled by default I faced problem with moxy, when some strategies not applied to view after configuration change. After digging into the problem I found that R8 remove *Command classes which have analogs with same fields within view state class. F.e:

data class SetImageCommand(
    val imageResId: Int,
): ViewCommand(tag = "setImage", strategy = AddToEndSingleStrategy.class)

and

data class SetMaxInputLengthCommand(
    val length: Int,
): ViewCommand(tag = "setMaxInputLength", strategy = AddToEndSingleStrategy.class)

One of the classes would be removed by R8, because both of them take only one Int parameter in constructor. It leads to 'overwriting' command stack by subsequent command:

viewState.setImage(R.drawable.ic_arrow /* imageResId = 81264 */)
viewState.setMaxInputLength(length = 10)

setMaxInputLength after minification uses SetImageCommand class, then after configuration change instead of expected execution of both commands we get only one executed command with wrong parameters (SetImageCommand(imageResId = 10)).

Solution

We need to tell R8 keep all classes that extends ViewCommand. You can use these rules:

-keep,allowobfuscation class * extends moxy.viewstate.MvpViewState { *; }
-keep,allowobfuscation class * extends moxy.viewstate.ViewCommand { *; }