将multidex APK部署到结构测试版时,Android ART NoClassDefFoundError

时间:2018-09-09 10:36:11

标签: java android kotlin compilation android-runtime

我有一个奇怪的问题。

我的multidix混合Java-kotlin应用程序内部有一段kotlin代码,可对字典进行排序。 (下面的代码)

在开发电话(SAMSUNG s9)上运行应用程序时,一切运行正常。 将应用程序部署到Fabric的“测试版”时,很大一部分用户(50%)的崩溃类型为NoClassDefFoundError。 受影响的手机包括xioami的MI 5s和Red-mi手机以及多种类型的onePlus手机

我试图查看输出apk(通过build-> Analyze APK),并确保该类确实存在。正如您从this image所看到的-该类实际上位于主“ classes.dex”文件上。

任何帮助将不胜感激!

日志文件:

  

...(在启动级别从应用程序进行自定义日志记录)

     

09-09 13:04:31.667 17365-17365 / com.example.orcam.basic_recognition_app   I / art:拒绝对先前失败的类java.lang.Class<com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2>

重新初始化      

...(在正常运行级别上从应用程序自定义日志记录)

     

09-09 13:04:31.762 17365-17365 / com.example.orcam.basic_recognition_app   E / AndroidRuntime:致命异常:main       流程:com.example.orcam.basic_recognition_app,PID:17365       java.lang.NoClassDefFoundError: com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2           在com.example.orcam.logic_myme.ComputedData.ComputedPersonData.calculateMeetingsForPerson(ComputedPersonData.kt:45)           在com.example.orcam.logic_myme.ComputedData.ComputedData.calculate(ComputedData.kt:7)           在com.example.orcam.logic_myme.db.DBManager $ init $ 2.onDbInitAndReady(DBManager.kt:79)           在com.example.lib_sync.sync.SyncManager2。(SyncManager2.java:63)           在com.example.orcam.logic_myme.db.DBManager.init(DBManager.kt:76)           在com.example.orcam.basic_recognition_app.LogicManager.init(LogicManager.java:58)           在com.example.orcam.basic_recognition_app.MyMeApplication.initManagers(MyMeApplication.kt:31)           在com.example.orcam.basic_recognition_app.MyMeApplication.onCreate(MyMeApplication.kt:13)           在android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1014)           在android.app.ActivityThread.handleBindApplication(ActivityThread.java:4782)           在android.app.ActivityThread.access $ 1700(ActivityThread.java:153)           在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1445)           在android.os.Handler.dispatchMessage(Handler.java:102)           在android.os.Looper.loop(Looper.java:154)           在android.app.ActivityThread.main(ActivityThread.java:5544)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:739)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)09-09   13:04:31.763 17365-17365 / com.example.orcam.basic_recognition_app   E / MQSEventManagerDelegate:无法获取MQSService。

build.gradle文件:

buildscript {
    repositories {
        maven { url 'https://maven.fabric.io/public' }
        google()
    }

    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

repositories {
    maven { url 'https://maven.fabric.io/public' }
    google()
}


android {
    compileSdkVersion 27
    buildToolsVersion "27.0.3"

    defaultConfig {
        applicationId "com.example.orcam.basic_recognition_app"
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 29
        versionName "5.0.9"

    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }

        beta {
            initWith debug
            applicationIdSuffix ""
        }



        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        pickFirst 'META-INF/LICENSE'
        pickFirst 'META-INF/DEPENDENCIES'
        pickFirst 'META-INF/ASL-2.0.txt'
        pickFirst 'META-INF/LGPL-3.0.txt'
        exclude 'META-INF/main.kotlin_module'
    }
    dexOptions {
        preDexLibraries = false
    }
}

ext {
    supportLibVersion = '27.1.1'
}

dependencies {
    /* ... a lot of dependencies ... */

    // multi dex
    implementation 'com.android.support:multidex:1.0.3'

    // kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

}
kapt {
    generateStubs = true
}

ComputedPersonData.kt文件(仅具有“不良”功能的简化版本):

class ComputedPersonData() {
    var meetingsByPerson = mapOf<String, ArrayList<String>>()

    fun calculateMeetingsForPerson() {
        val faces: Map<String: Face?> = getFaces()
        val faceToContact: Map<String: String?> = getMapping()
        val peopleWithFaces = mutableMapOf<String, ArrayList<Face>>()


        faces.values.forEach {
            if (it != null) {
                val personId = faceToContact[it.imageId] ?: ""

                val list = peopleWithFaces[personId] ?: run {
                    peopleWithFaces[personId] = arrayListOf(it)
                    return@forEach
                }
                list.add(it)
            }
        }

        val dictSorted = mutableMapOf<String, ArrayList<Face>>()
        peopleWithFaces.forEach { id, item ->
            dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
        }

// the "dictSorted.mapValues{}" generates the "bad" $2 class

        val dictFaceToString: Map<String, ArrayList<String>> = dictSorted.mapValues {
            ArrayList(it.value.map {
                it.id
            }
            )
        }

        this.meetingsByPerson = dictFaceToString
    }
}

应用程序类:

class MyApplication : MultiDexApplication()

1 个答案:

答案 0 :(得分:0)

好吧,经过MONTHS的调查后,明显的坏处是-

peopleWithFaces.forEach { id, item ->
            dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
        }

旧的android-OS(特定于6.0.0)和Kotlin的for-each分离时出现问题。

一旦发现问题,解决方案就很容易。我们需要做的就是像这样重新编写这种乐趣:

peopleWithFaces.forEach { 
            val id = it.key
            val item = it.value
            dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
        }