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/
}
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.