我有一个奇怪的问题。
我的 multidix 混合 java-kotlin 应用程序中有一段对字典进行排序的 kotlin 代码。 (代码如下)
在开发手机(SAMSUNG s9)上运行应用程序时,一切运行正常。
当将该应用程序部署到 Fabric 的“测试版”时,很大一部分 (50%) 的用户遇到 NoClassDefFoundError
类型的崩溃。 。
受影响的手机包括小米的小米5s和红米手机以及多款一加手机
我尝试查看输出的 apk(通过构建 -> 分析 APK)并确保该类确实存在。从可以看出- 该类实际上位于主“classes.dex”文件中。
任何帮助将不胜感激!
日志文件:
... (custom logging from the app on initiation level)
09-09 13:04:31.667 17365-17365/com.example.orcam.basic_recognition_app I/art: Rejecting re-init on previously-failed class
java.lang.Class<com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2>
... (custom logging from the app on normal run level)
09-09 13:04:31.762 17365-17365/com.example.orcam.basic_recognition_app E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.orcam.basic_recognition_app, PID: 17365
java.lang.NoClassDefFoundError: com.example.orcam.logic_myme.ComputedData.ComputedPersonData$calculateMeetingsForPerson$2
at com.example.orcam.logic_myme.ComputedData.ComputedPersonData.calculateMeetingsForPerson(ComputedPersonData.kt:45) at com.example.orcam.logic_myme.ComputedData.ComputedData.calculate(ComputedData.kt:7) at com.example.orcam.logic_myme.db.DBManager$init$2.onDbInitAndReady(DBManager.kt:79) at com.example.lib_sync.sync.SyncManager2.(SyncManager2.java:63) at com.example.orcam.logic_myme.db.DBManager.init(DBManager.kt:76) at com.example.orcam.basic_recognition_app.LogicManager.init(LogicManager.java:58) at com.example.orcam.basic_recognition_app.MyMeApplication.initManagers(MyMeApplication.kt:31) at com.example.orcam.basic_recognition_app.MyMeApplication.onCreate(MyMeApplication.kt:13) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1014) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4782) at android.app.ActivityThread.access$1700(ActivityThread.java:153) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1445) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:5544) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) at 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: failed to get 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
}
CompulatedPersonData.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()
最佳答案
好吧,经过几个月的调查,显然坏线是 -
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 })
}
关于java - 将 multidex apk 部署到 Fabric Beta 时出现 android ART NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52243627/