Kotlin suspend function not running with Proguard rules

71 views Asked by At

I keep getting the following crash when making a Retrofit2 call using coroutines when proguard rules are applied with release builds.

I've tried various rules but they all result in the same crash.

FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.example.jampez, PID: 23637
java.lang.ClassCastException
at androidx.activity.h.o(Unknown Source:5)
at r3.g.invokeSuspend(Unknown Source:54)
at s5.a.resumeWith(Unknown Source:8)
at l8.b0.run(Unknown Source:108)
at h.j.run(Unknown Source:11)
at r8.k.run(Unknown Source:2)
at r8.b.run(Unknown Source:95)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [e1{Cancelling}@9f17182, Dispatchers.IO]

This is the code being called in a viewModel:

fun fetchUser(emailInput: String, passwordInput: String) {

    viewModelScope.launch(IO) {
        val usersResponse = userRepository.fetchUsers()

        usersResponse.let { response ->

            if(response.success) {
                val users = response.body?.users

                val user = users?.find { it.email == emailInput && it.password == passwordInput }

                val userId = if (saveDatabasePassPhrase(user?.password) && saveUser(user)) {
                    user?.id
                } else {
                    null
                }
                _userIdState.postValue(userId)
            } else {
                _userIdState.postValue(null)
            }
        }
    }
}

These are the data classes being used:

data class FetchUsers(
    val users: List<User>
)

data class User(
    var id: Long,
    var firstName: String,
    var email: String,
    var password: String,
    var image: String,
)

Here are the current rules:

-dontwarn okhttp3.**
-dontwarn retrofit2.**

# Preserve the line number information for debugging stack traces.
-keepattributes Exceptions,*Annotation*,InnerClasses,SourceFile,LineNumberTable,Deprecated
-keep public class * extends java.lang.Exception


# glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
 <init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
  *** rewind();
}

-keepattributes Signature
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keepattributes AnnotationDefault,RuntimeVisibleAnnotations
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-keep class com.google.gson.** { *; }
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-keepattributes Annotation
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn org.conscrypt.*

# lifecycle process
-keepclassmembers class * extends androidx.lifecycle.EmptyActivityLifecycleCallbacks { *; }

# Room
-keep class androidx.room.RoomDatabase { *; }
-keep class androidx.room.Room { *; }
-keep class android.arch.** { *; }

# SqlCipher
-keep class net.sqlcipher.** { *; }
-dontwarn net.sqlcipher.**
-keep public class net.sqlcipher.** {
    *;
}

-keep public class net.sqlcipher.database.** {
    *;
}



# Statically guarded by try-catch block and not used on Android, see CacheByClass
-dontwarn java.lang.ClassValue

# Junit
-dontwarn android.test.**

# appcompat
# Ensure that reflectively-loaded inflater is not obfuscated. This can be
# removed when we stop supporting AAPT1 builds.
-keepnames class androidx.appcompat.app.AppCompatViewInflater
# aapt is not able to read app::actionViewClass and app:actionProviderClass to produce proguard
# keep rules. Add a commonly used SearchView to the keep list until b/109831488 is resolved.
-keep class androidx.appcompat.widget.SearchView { <init>(...); }

# Material
# CoordinatorLayout resolves the behaviors of its child components with reflection.
-keep public class * extends androidx.coordinatorlayout.widget.CoordinatorLayout$Behavior {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>();
}

# Make sure we keep annotations for CoordinatorLayout's DefaultBehavior
-keepattributes RuntimeVisible*Annotation*

# leakcanary
-dontwarn com.squareup.haha.guava.**
-dontwarn com.squareup.haha.perflib.**
-dontwarn com.squareup.haha.trove.**
-dontwarn com.squareup.leakcanary.**
-keep class com.squareup.haha.** { *; }
-keep class com.squareup.leakcanary.** { *; }

-keepclassmembers enum * { *; }

-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE

Here is the app gradle:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'com.google.devtools.ksp'
    id 'kotlin-kapt'
    id 'androidx.navigation.safeargs.kotlin'
}

android {
    namespace 'com.example.jampez'
    compileSdk 34

    defaultConfig {
        applicationId "com.example.jampez"
        minSdk 26
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled true
            debuggable false
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_20
        targetCompatibility JavaVersion.VERSION_20
    }
    kotlinOptions {
        jvmTarget = '20'
    }

    buildFeatures {
        dataBinding true
        viewBinding true
    }
}

dependencies {

    implementation 'androidx.security:security-crypto:1.0.0'
    implementation 'com.scottyab:rootbeer-lib:0.0.7'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
    implementation 'com.github.bumptech.glide:glide:4.16.0'

    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.7.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.7.1'

    //okhttp
    implementation 'com.squareup.okhttp3:okhttp:4.3.1'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.3.1'


    implementation 'androidx.lifecycle:lifecycle-process:2.6.2'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.core:core-splashscreen:1.0.1'

    implementation 'androidx.room:room-runtime:2.6.1'
    ksp 'androidx.room:room-compiler:2.6.1'
    implementation 'androidx.room:room-ktx:2.6.1'
    implementation 'net.zetetic:android-database-sqlcipher:4.5.4'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'androidx.core:core-ktx:1.12.0'

    implementation 'androidx.navigation:navigation-fragment-ktx:2.7.6'
    implementation 'androidx.navigation:navigation-ui-ktx:2.7.6'

    implementation "org.jetbrains.kotlin:kotlin-reflect:1.9.21"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"

    // Koin
    implementation 'io.insert-koin:koin-android:3.5.0'
    implementation 'io.insert-koin:koin-androidx-navigation:3.5.0'
    implementation 'io.insert-koin:koin-androidx-workmanager:3.5.0'

    testImplementation "junit:junit:4.13.2"
    testImplementation "io.insert-koin:koin-test:3.5.0"
    testImplementation "io.insert-koin:koin-test-junit4:3.5.0"
    testImplementation "io.insert-koin:koin-test-junit5:3.5.0"

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.11.0'

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
}

Project Gradle:

buildscript {
    ext.kotlin_version = '1.9.21'

    repositories {
        google()
        mavenCentral()
        maven { url 'https://plugins.gradle.org/m2' }
        maven { url 'https://jitpack.io' }
    }
    dependencies {
        classpath 'com.google.gms:google-services:4.4.0'
        classpath 'com.android.tools.build:gradle:8.2.0'
        classpath 'com.google.firebase:firebase-plugins:2.0.0'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:1.9.21-1.0.15'
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.6"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

tasks.register('clean', Delete) {
    delete rootProject.buildFile
}
0

There are 0 answers