android ART NoClassDefFoundError при развертывании multidex apk в Fabric beta - PullRequest
0 голосов
/ 09 сентября 2018

У меня странная проблема.

У меня есть фрагмент кода kotlin, который сортирует словарь, внутри моего мультидикс-смешанного приложения java-kotlin. (код ниже)

при запуске приложения на телефоне для разработчиков (SAMSUNG s9) все работает нормально. При развертывании приложения в бета-версии Fabric большая часть (50%) пользователей имеют сбои типа NoClassDefFoundError. К числу затронутых телефонов относятся телефоны Mio 5s и Red-mi от xioami, а также несколько типов телефонов 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: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: главная Процесс: 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 голосов
/ 13 февраля 2019

хорошо, после МЕСЯЦЕВ исследования, очевидно, плохие строки были -

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

Возникла проблема со старой ОС Android (специфичной для 6.0.0) и отделенной от kotlin for-each.

Как только проблема обнаружена, решение стало простым. Все, что нам нужно было сделать, это переписать это удовольствие так:

peopleWithFaces.forEach { 
            val id = it.key
            val item = it.value
            dictSorted[id] = ArrayList(item.sortedBy { it.timestamp })
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...