Search code examples
androidproguardmoshiandroid-r8

Enable R8 when using moshi-kotlin-codegen


I am trying to enable R8 for my project : https://github.com/alirezaeiii/TMDb-Compose-Playground

buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

I am using moshi to map my json responses and I have added mishi-kotlin-codegen. Here is a sample of my Response class :

@JsonClass(generateAdapter = true)
data class NetworkMovie(
    @Json(name = ID)
    override val id: Int,
    @Json(name = OVERVIEW)
    override val overview: String,
    @Json(name = RELEASE_DATE)
    override val releaseDate: String?,
    @Json(name = POSTER_PATH)
    override val posterPath: String?,
    @Json(name = BACKDROP_PATH)
    override val backdropPath: String?,
    @Json(name = TITLE)
    override val name: String,
    @Json(name = VOTE_AVERAGE)
    override val voteAverage: Double,
    @Json(name = VOTE_COUNT)
    override val voteCount: Int
) : NetworkTMDbItem

As you see I am using @JsonClass(generateAdapter = true) and I got proguard configuration from https://github.com/square/moshi/blob/master/moshi/src/main/resources/META-INF/proguard/moshi.pro :

# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**

-keepclasseswithmembers class * {
    @com.squareup.moshi.* <methods>;
}

-keep @com.squareup.moshi.JsonQualifier @interface *

# Enum field names are used by the integrated EnumJsonAdapter.
# values() is synthesized by the Kotlin compiler and is used by EnumJsonAdapter indirectly
# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi.
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
    <fields>;
    **[] values();
}

# Keep helper method to avoid R8 optimisation that would keep all Kotlin Metadata when unwanted
-keepclassmembers class com.squareup.moshi.internal.Util {
    private static java.lang.String getKotlinMetadataClassName();
}

# Keep ToJson/FromJson-annotated methods
-keepclassmembers class * {
  @com.squareup.moshi.FromJson <methods>;
  @com.squareup.moshi.ToJson <methods>;
}

When I build the release variant, it successfully get built but when I run the apk file on my device, it fails in the network calls.

Is there something that I am missing?


Solution

  • R8 full mode strips generic signatures from non-kept items so you need to add these rules in your proguard file:

    -keep,allowobfuscation,allowshrinking interface retrofit2.Call
    -keep,allowobfuscation,allowshrinking class retrofit2.Response
    -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
    

    Regarding your code, you've not used Call and Response in your project (according to what I saw in your repository) so you can ignore the first two -keeps and just use the third one because of using Coroutine.