androidkotlinurbanairship.com

Error on installing the app when minify = true


I'm developing an app where I'm using urbanairship, the app is builded properly and it is installed properly also but when it is initialised something make it crash but only if minify true, if it is false it run perfectly fine.

the error:

I already tried to implement multidex but without success

The error:

Process: qa.vodafone.myvodafone.prd, PID: 24925 java.lang.NoSuchMethodError: No virtual method object()Lj/c/f; in class Lj/c/f; or its super classes (declaration of 'j.c.f' appears in base.apk) at c.n.k.d.a(Unknown Source:0) at c.n.k.d.toString(Unknown Source:5) at com.urbanairship.job.AirshipService.a(:2) at c.n.i.h.a(:9) at c.n.s.c.a(:2)

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'

apply plugin: 'com.google.gms.google-services'

apply plugin: 'io.fabric'

apply plugin: "com.soasta.mpulse.android"

android {
    signingConfigs {



    }
    compileSdkVersion 28
    defaultConfig {
        applicationId ""
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 224
        versionName "10.0.0"


    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            debuggable = false
            jniDebuggable = false
            renderscriptDebuggable = false
            signingConfig signingConfigs.releaseTest
        }
    }

    flavorDimensions "default"

    productFlavors {


    }


    def name = "mva"

    applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "${name}_${variant.name}_${versionName}.apk"
        }
    }

    lintOptions {
        disable 'TypographyFractions', 'TypographyQuotes'
        enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled'
        check 'NewApi', 'InlinedApi'
        quiet false
        abortOnError true
        ignoreWarnings true
        checkAllWarnings true
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    dataBinding {
        enabled = true
    }

    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }


}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
    implementation 'androidx.core:core-ktx:1.2.0-alpha03'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation "com.airbnb.android:lottie:$lottie_version"
    implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
    implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'
    testImplementation 'org.mockito:mockito-core:1.10.19'
    implementation "android.arch.lifecycle:extensions:1.1.1"
    implementation "android.arch.lifecycle:viewmodel:1.1.1"
    implementation "android.arch.lifecycle:livedata:1.1.1"

    implementation "com.squareup.moshi:moshi-kotlin:1.8.0"
    implementation "com.squareup.moshi:moshi-adapters:1.5.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
    implementation 'com.google.android.material:material:1.0.0'

    implementation 'com.github.bumptech.glide:glide:4.9.0'
    kapt 'com.github.bumptech.glide:compiler:4.9.0'


    implementation "com.microsoft.appcenter:appcenter-analytics:${appCenterSdkVersion}"
    implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"

    implementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
    implementation 'com.android.support:preference-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:support-v4:28.1.0'
    implementation "com.google.android.gms:play-services-maps:${gmsServicesVersion}"
    implementation "com.google.android.gms:play-services-location:${gmsServicesVersion}"
    implementation "com.google.android.gms:play-services-analytics:${gmsServicesVersion}"
    implementation 'com.google.android.libraries.places:places:2.0.0'
    implementation 'com.google.maps:google-maps-services:0.2.4'
    implementation 'com.google.maps.android:android-maps-utils:0.5'
    implementation 'com.google.android.gms:play-services-auth:17.0.0'

    implementation 'androidx.browser:browser:1.0.0'
    implementation 'androidx.biometric:biometric:1.0.0-alpha04'

    implementation 'com.gauravbhola.ripplepulsebackground:library:1.0.0'
    implementation 'me.everything:overscroll-decor-android:1.0.4'

    // Airship SDK - FCM
    implementation 'com.urbanairship.android:urbanairship-fcm:10.0.2'

    // Firebase
    implementation 'com.google.firebase:firebase-core:17.0.1'
    implementation 'com.google.firebase:firebase-iid:19.0.1'
    implementation 'com.google.firebase:firebase-messaging:19.0.1'




    //Adobe Analytics
    implementation 'com.adobe.mobile:adobeMobileLibrary:4.17.9'
    //implementation 'com.adobe.marketing.mobile:sdk-core:1.4.0'
    //implementation 'com.adobe.marketing.mobile:target:1.1.1'

    // Tealium
    implementation 'com.tealium:library:5.5.4'
    implementation 'com.tealium:lifecycle:1.1.2'
    implementation('com.soasta.mpulse:mpulse-android:2.6.3') {
        exclude group: 'org.json', module: 'json'
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'
        exclude group: "com.android.tools.build", module: "gradle"
    }

    //Zopim Chat
    implementation group: 'com.zopim.android', name: 'sdk', version: '1.4.1'

    implementation 'com.github.zcweng:switch-button:0.0.3@aar'

    implementation ('com.crashlytienter code herecs.sdk.android:crashlytics:2.10.1@aar') {
        transitive = true
    }

}

mpulseAndroid {
    exclude ~/.*classes.jar/
}

Solution

  • This, from what I've learnt, is a common problem you'll run into when you first enable minifying. The minifier (ProGuard or R8) removes any method that is not directly referenced within your code, as part of its efforts to make your APK smaller. This feature is incredibly useful - when I first used it, it removed so many unused methods from my APK that I didn't need MultiDex anymore.

    But it causes a problem - sometimes there are methods that might never be directly called in your code, but get called via reflection or in generated code, for example @Subscribe methods when using Otto/EventBus and @OnClick methods when using ButterKnife. The minifier wrongly removes these methods too, and you only find out after building and running when you get the NoSuchMethodError. And even worse, you don't know which method got wrongly removed because the method names are obfuscated with names like j.c.f.

    Here is how I solved it. First, disable obfuscation so you can see which methods are wrongly removed. Add the following to proguard-rules.pro.

    -dontobfuscate
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
    -keepattributes *Annotation*
    

    Then when you run again, instead of seeing j.c.f, you will know exactly which method got removed. Then you can tell the minifier to keep it. If the method is in your own package and not in an included library, the laziest way to fix this (which I went it) is to just tell the minifier to keep all the methods in your package. So if your package is com.ccbernardo, then add this to proguard-rules.pro.

    -keepclassmembers class com.ccbernardo.** {
        public *;
        protected *;
    }
    

    There are other ways to keep members. For example, to keep all members with the annotation org.greenrobot.eventbus.Subscribe, add

    -keepclassmembers class ** {
        @org.greenrobot.eventbus.Subscribe public *;
    }
    

    I use these because I don't know much about ProGuard, so I don't know how to make the rules more specific. You can read more about the ProGuard syntax online, but I hope this helps.