Android应用程序在Samsung Lollipop设备上崩溃NoClassDefFoundError [英] Android app crash NoClassDefFoundError on Samsung Lollipop devices

查看:120
本文介绍了Android应用程序在Samsung Lollipop设备上崩溃NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近将应用程序的minSdkVersion从16(豆形软糖)提高到21(棒棒糖).尽管我们主要使用调试版本对应用程序进行了广泛的测试,但我们现在在应用程序启动时面临着大量的生产崩溃,主要是在较旧的三星设备上-(Note3和S4是最主要的崩溃者),并且始终在Lollipop上.

We recently bumped the minSdkVersion of our app from 16 (Jellybean) to 21 (Lollipop). Although we did extensive testing with our app predominantly using debug builds, we are now facing a slew of production crashes at app startup, predominantly on older Samsung devices - (Note3 and S4 are the top crashers) and always on Lollipop.

错误是

Fatal Exception: java.lang.NoClassDefFoundError: com.retailconvergence.ruelala.delegate.GoogleLoginDelegate
   at com.retailconvergence.ruelala.delegate.LifecycleDelegateManager.addDelegateOfType(LifecycleDelegateManager.java:48)
   at com.retailconvergence.ruelala.extensions.activity.LifecycleDelegateActivity.addDelegateOfType(LifecycleDelegateActivity.java:55)
   at com.retailconvergence.ruelala.activity.SplashActivity.setupDelegates(SplashActivity.java:198)
   at com.retailconvergence.ruelala.activity.SplashActivity.onCreate(SplashActivity.java:60)
   at android.app.Activity.performCreate(Activity.java:6288)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
   at android.app.ActivityThread.access$900(ActivityThread.java:177)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:5942)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

SplashActivity是应用程序的初始启动活动.未找到的类是一个由来已久的类,不是新引入的类.附带说明一下,作为此最新版本的一部分,我们升级到了Android Studio 3并引入了Kotlin代码,但我认为这些与问题无关.我们没有在构建中使用proguard.

The SplashActivity is the initial lauching activity of the app. The class not found is a long-established class not something newly introduced. As a side note, as part of this latest release we upgraded to Android Studio 3 and introduced Kotlin code, but I dont think these are related to the issue. We are not using proguard in the build.

我知道当minSdkVersion为21及更高版本时,构建会发生重大变化,这与使用ART而不是Dalvik有关,所以我想知道Samsung Lollipop设备是否仍存在一些缺陷现在在主要dex文件中有一个类吗?

I'm aware that there was a significant change for builds when the minSdkVersion is 21 and above, relating to the use of ART instead of Dalvik, so I'm wondering if there is some flaw with Samsung Lollipop devices still looking for a class in the primary dex file now?

模块级build.gradle:

The module-level build.gradle:

import java.text.SimpleDateFormat
import java.util.concurrent.TimeUnit

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
apply plugin: 'spoon'

// Manifest version information
def versionMajor = 4
def versionMinor = 2
def versionPatch = 0
def versionBuild = 0  // bump for dogfood builds, public betas, etc.
ext.versionReleaseDate="OCT-13-2017"    // UPDATE THIS WHEN YOU BUMP THE VERSIONS ABOVE FOR A NEW RELEASE MMM-dd-yyy


repositories {
    mavenCentral()
    maven { url 'https://maven.fabric.io/public' }
    maven { url 'http://salesforce-marketingcloud.github.io/JB4A-SDK-Android/repository' }
    maven { url "https://maven.google.com" }
    maven { url "http://maven.tealiumiq.com/android/releases/" }
}

def getCountOfHoursSinceVersionUpdate() {
    def currentDate = new Date()
    def format = new SimpleDateFormat("MMM-dd-yyyy")
    def buildDate = (Date)format.parse(versionReleaseDate)
    return (Integer)((currentDate.getTime() - buildDate.getTime()) / TimeUnit.HOURS.toMillis(1))
}

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.1'

    defaultConfig {
        targetSdkVersion 25

        /**
         * Increment versionCode by commit count
         */

        versionCode       versionMajor * 100000 + versionMinor * 10000 + versionPatch * 1000 + versionBuild + getCountOfHoursSinceVersionUpdate()


        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // Enabling multidex support. :(
        multiDexEnabled true

        def manifestPath = project(':').file('app/src/androidTest/AndroidManifest.xml')
        buildConfigField "String", "MANIFEST_PATH", "\"" + manifestPath + "\""

        def resPath = project(':').file('app/src/main/res/')
        buildConfigField "String", "RES_PATH", "\"" + resPath + "\""

        def assetPath = project(':').file('app/src/prod/assets/')
        buildConfigField "String", "ASSET_PATH", "\"" + assetPath + "\""

    }

    dexOptions {
        javaMaxHeapSize "8g"
        dexInProcess true // the magic line
    }


    flavorDimensions "debugDimension"

    /**
     * productFlavors override defaultConfig properties as well as force gradle to look in the new
     * folders that we have created to differentiate the build assets and manifests.
     * src/dev, src/prod
     */
    productFlavors {
        dev    {
            minSdkVersion 21
            applicationId "com.retailconvergence.ruelala.dev"
            versionName "${versionMajor}.${versionMinor}.0${versionPatch}"
            manifestPlaceholders = [optimizelyId: "optly4740131949"]
            dimension "debugDimension"
        }

        prod {
            minSdkVersion 21
            applicationId "com.retailconvergence.ruelala"
            versionName "${versionMajor}.${versionMinor}.${versionPatch}"
            manifestPlaceholders = [optimizelyId: "optly4752051515"]
            dimension "debugDimension"
        }
    }

    signingConfigs {
        prod {
            //the key is up a level, don't include in the modules
            storeFile file("../RueLaLaKeystore")
            storePassword "Boutiques"
            keyAlias "rue la la"
            keyPassword "Boutiques"
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.prod


            ext.betaDistributionReleaseNotesFilePath = 'release_notes.txt'
            ext.betaDistributionGroupAliases = 'AndroidTesters'
            ext.betaDistributionNotifications = true
        }

        debug {
            versionNameSuffix '-dev'

            signingConfig signingConfigs.prod
            // to get coverage report, set testCoverageEnabled to true and run gradle task called createDevelopmentDebugAndroidTestCoverageReport
            // Note that test coverage doesn't seem to work on Samsung devices, other brand or emulator should work though
            testCoverageEnabled = false

            ext.betaDistributionReleaseNotesFilePath = 'release_notes.txt'
            ext.betaDistributionGroupAliases = 'AndroidTesters'
            ext.betaDistributionNotifications = true

        }
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'LICENSE.txt'
        exclude 'LICENSE'
        exclude 'READ.ME'
        exclude 'README'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

configurations {
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    //include our modules
    compile project(':core')
    compile project(':data')

    //android
    final APP_COMPAT_VERSION = '26.1.0'

    compile "com.android.support:appcompat-v7:$APP_COMPAT_VERSION"
    compile "com.android.support:recyclerview-v7:$APP_COMPAT_VERSION"
    compile "com.android.support:design:$APP_COMPAT_VERSION"
    compile "com.android.support:multidex:1.0.0"
    compile "com.android.support:cardview-v7:$APP_COMPAT_VERSION"

    // google
    final PLAY_SERVICES_VERSION = '10.2.4'
    compile "com.google.android.gms:play-services-wallet:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-location:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-gcm:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-plus:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-identity:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-analytics:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-auth:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-maps:$PLAY_SERVICES_VERSION"

    // facebook

    compile 'com.facebook.android:facebook-android-sdk:4.8.+'
    compile 'com.facebook.stetho:stetho:1.1.0'

    //markdown4j
    compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0'

    //crashlytics
    compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') {
        transitive = true;
    }

    //image zoom
    compile 'com.github.chrisbanes.photoview:library:1.2.3'

    //square
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.makeramen:roundedimageview:2.2.1'


    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
    testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'

    compile 'com.jakewharton:butterknife:8.6.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'

    // optimizely
    compile('com.optimizely:optimizely:1.4.2@aar') {
        transitive = true
    }

    //braintree
    compile 'com.braintreepayments.api:braintree:2.6.0'
    compile 'com.braintreepayments.api:data-collector:2.+'

    // guava
    compile 'com.google.guava:guava:19.0'

    // sticky headers
    compile 'com.github.mtotschnig:StickyListHeaders:2.7.1'

    // expandable recyclerview
    compile 'eu.davidea:flexible-adapter:5.0.0-rc2'

    //recyclerview animations
    compile 'jp.wasabeef:recyclerview-animators:2.2.3'

    // tooltip
    compile 'com.github.michaelye.easydialog:easydialog:1.4'

    // tealium
    compile 'com.tealium:library:5.3.0'

    // circle indicator
    compile 'me.relex:circleindicator:1.2.2@aar'

    //testing
    final HAMCREST_VERSION = '1.3'

    def jUnit = "junit:junit:4.12"

    // ExactTarget SDK
    compile ('com.salesforce.marketingcloud:marketingcloudsdk:5.0.5') {
        exclude module: 'android-beacon-library' //remove to use Proximity messaging
        exclude module: 'play-services-location' //remove to use Geofence or Proximity messaging
    }

    androidTestCompile jUnit

    // Unit tests dependencies
    testCompile jUnit
    testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION"
    testCompile "org.hamcrest:hamcrest-library:$HAMCREST_VERSION"
    testCompile "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION"
    testCompile 'org.robolectric:robolectric:3.1'
    testCompile 'org.mockito:mockito-core:1.+'
    testCompile 'com.google.guava:guava:19.0'
    testCompile("com.android.support:support-v4:$APP_COMPAT_VERSION") {
        exclude module: 'support-annotations'
    }
    testCompile('org.powermock:powermock-api-mockito:1.6.4') {
        exclude module: 'objenesis'
    }
    testCompile('org.powermock:powermock-module-junit4:1.6.4') {
        exclude module: 'objenesis'
    }
    testCompile 'io.reactivex:rxandroid:1.0.1'
    testCompile 'io.reactivex:rxjava:1.1.0'

    // Espresso
    androidTestCompile('com.android.support.test:runner:0.5') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test:rules:0.5') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'appcompat-v7'
        exclude module: 'design'
        exclude module: 'support-v4'
    }

    // allows java 8 compile
    compile 'com.annimon:stream:1.1.2'

    // For taking screenshots
    androidTestCompile 'com.squareup.spoon:spoon-client:1.7.0'

    testCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
    compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}

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

spoon {
    noAnimations = true
    grantAllPermissions = true
}

apply plugin: 'devicefarm'

devicefarm {
    projectName "Rue Mobile"
    devicePool "Smoke Test Pool"
    useUnmeteredDevices()
    authentication {
        accessKey System.getenv("AWS_DEVICE_FARM_ACCESS_KEY")
        secretKey System.getenv("AWS_DEVICE_FARM_SECRET_KEY")
    }
}

推荐答案

此问题的解决方法是禁用预删除:

The fix for this was to disable pre-dexing:

dexOptions {
    preDexLibraries false
}

在应用程序build.gradle中

.来自此链接的灵感来自有关Lollipop上未找到Picasso类的错误的链接:

in the app build.gradle. Inspiration for this came from this link regarding a Picasso class not found error on Lollipop: see here

我尚不完全清楚为什么禁用预排序解决了问题,但我只能得出结论,构建过程中正在进行一些优化,这会影响apk的dex文件中类的排序方式,然后影响这些三星Lollipop设备上的应用安装.从理论上讲,ART应该解决所有这些问题,但是很显然,pre-dex优化与某些Lollipop设备之间存在依赖关系.

Its not entirely clear to me why disabling pre-dexing solves the problem, but I can only theorize that there is some optimization going on with the build process that affects the way classes are ordered in the dex files of the apk that then affects the app installation on these Samsung Lollipop devices. In theory ART should take care of all of that, but clearly there is a dependency between pre-dex optimization and some Lollipop devices.

这篇关于Android应用程序在Samsung Lollipop设备上崩溃NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆