最近,當我在家用我的電腦用Windows 8.1完成我的工作時,發現項目無法正常工作 - 編譯,在仿真器上運行並在某些特定點崩潰(它可以在我的PC上100%重現)。Android項目中的ClassNotFoundException僅在我的PC上
但是,同一個存儲庫版本可以在Mac上工作,也可以在同事的Windows 10機器上工作。
每個提到的環境都使用Android Studio 2.3.1,gradle 3.3和Kotlin 1.1.1,並在API 25 x86_64映像上運行應用程序。
該項目使用multidex 1.0.1庫。
的崩潰發生是由於以下異常:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.project.app, PID: 2533
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/project/package/SomeActivityKt$sam$Action1$22181393;
at com.project.package.SomeActivity.getDataFor(SomeActivity.kt:164)
at com.project.package.SomeActivity.getData(SomeActivity.kt:147)
at com.project.package.SomeActivity.onResume(SomeActivity.kt:142)
at android.app.Instrumentatcomn.callActivityOnResume(Instrumentatcomn.java:1269)
at android.app.Activity.performResume(Activity.java:6783)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.project.package.SomeActivityKt$sam$Action1$22181393" on path: DexPathList[[zip file "/data/app/com.project.app-1/base.apk", zip file "/data/app/com.project.app-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.project.app-1/lib/x86_64, /data/app/com.project.app-1/base.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_dependencies_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_0_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_1_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_2_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_3_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_4_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_5_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_6_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_7_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_8_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_9_apk.apk!/lib/x86_64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.project.package.SomeActivity.getDataFor(SomeActivity.kt:164)
at com.project.package.SomeActivity.getData(SomeActivity.kt:147)
at com.project.package.SomeActivity.onResume(SomeActivity.kt:142)
at android.app.Instrumentatcomn.callActivityOnResume(Instrumentatcomn.java:1269)
at android.app.Activity.performResume(Activity.java:6783)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
BaseActivity.kt
abstract class BaseActivity : RxAppCompatActivity(), HasErrorHandler (...)
SomeActivity.kt - 這種崩潰
class SomeActivity : BaseActivity(), HasFullWindowProgress (...) {
(...)
private fun getDataFor(id: String) {
apiClient.somethingList(id)
.map { response -> response.toSomethingList() }
.lifecycle(this)
.showProgress(this)
.observeOnMainThread() // <== line 164
.subscribe({
LOG.info("Something list fetched ${it.size}")
adapter.setItems(it)
}, defaultOnError("Fetching something list failed"))
}
}
AnotherActivity.kt - 使用相同的功能,SomeActivity
和不會崩潰
class AnotherActivity : BaseActivity(), HasFullWindowProgress (...) {
(...)
private fun getData() {
somethingElse.user?.id?.let { id ->
apiClient.somethingElseList()
.map { response -> response.toAnotherList(id) }
.lifecycle(this)
.showProgress(this)
.observeOnMainThread()
.subscribe({
onNewSomethingElseList(id, it)
}, defaultOnError("Fetching somethingElseList for somethingElse failed"))
}
}
}
ActivityErrorHandlingExtensions.kt
fun <T> T.defaultOnError(message: String, vararg args: Any?): (Throwable) -> Unit where T : HasErrorHandler, T : Activity {
val targetClass = javaClass
val activity = this
return { err ->
val messageFormats = (args.toList() + err).toTypedArray()
LoggerFactory.getLogger(targetClass).error(message, *messageFormats)
errorHandler.default(err, activity)
}
}
ObservableExtensions.kt
fun <T> Observable<T>.lifecycle(activity: RxAppCompatActivity) : Observable<T> {
return compose(activity.bindToLifecycle<T>())
}
fun <T> Observable<T>.observeOnMainThread() : Observable<T> {
return observeOn(AndroidSchedulers.mainThread())
}
Progress.kt
fun <T> Observable<T>.showProgress(hasProgress: HasFullWindowProgress): Observable<T> {
return compose {
it.doOnSubscribe {
MAIN_THREAD_WORKER.schedule {
hasProgress.fullWindowProgress.visibility = View.VISIBLE
}
}.doAfterTerminate {
MAIN_THREAD_WORKER.schedule {
hasProgress.fullWindowProgress.visibility = View.GONE
}
}
}
}
所有這些代碼是在項目上一兩個月,並在兩個星期前,我的工作電腦上。
我已經嘗試過:
./gradlew cleanBuildCache
刪除
$HOME/.gradle/caches
刪除
$HOME/.android/build-cache
刪除
$HOME/.AndroidStudio2.3/system/caches
刪除
build
和app/build
迪爾斯在項目的根目錄中刪除
.gradle
DIRAndroid Studio中無效的緩存和重新啓動
手動卸載從模擬器的應用程序,並重新安裝它
重新安裝Android Studio 2.3.1
降級的Android工作室到2.3(這是我用了2個星期前的版本,我知道那麼它的工作)
任何想法有什麼不對嗎?該getDataFor
方法
科特林字節碼:
private final getDataFor(Ljava/lang/String;)V
L0
LINENUMBER 160 L0
L1
LINENUMBER 165 L1
L2
LINENUMBER 160 L2
L3
LINENUMBER 164 L3
L4
LINENUMBER 160 L4
L5
LINENUMBER 163 L5
L6
LINENUMBER 160 L6
L7
LINENUMBER 162 L7
L8
LINENUMBER 160 L8
L9
LINENUMBER 161 L9
L10
LINENUMBER 160 L10
ALOAD 0
GETFIELD com/project/package/SomeActivity.apiClient : Lcom/project/network/ApiClient;
DUP
IFNONNULL L11
LDC "apiClient"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
L11
ALOAD 1
INVOKEVIRTUAL com/project/network/ApiClient.somethingList (Ljava/lang/String;)Lrx/Observable;
GETSTATIC com/project/package/SomeActivity$getDataFor$1.INSTANCE : Lcom/project/package/SomeActivity$getDataFor$1;
CHECKCAST rx/functions/Func1
L12
LINENUMBER 161 L12
INVOKEVIRTUAL rx/Observable.map (Lrx/functions/Func1;)Lrx/Observable;
ALOAD 0
CHECKCAST com/trello/rxlifecycle/components/support/RxAppCompatActivity
L13
LINENUMBER 162 L13
INVOKESTATIC com/project/extensions/ObservableExtensionsKt.lifecycle (Lrx/Observable;Lcom/trello/rxlifecycle/components/support/RxAppCompatActivity;)Lrx/Observable;
ALOAD 0
CHECKCAST com/project/widgets/HasFullWindowProgress
L14
LINENUMBER 163 L14
INVOKESTATIC com/project/widgets/ProgressKt.showProgress (Lrx/Observable;Lcom/project/widgets/HasFullWindowProgress;)Lrx/Observable;
L15
LINENUMBER 164 L15
INVOKESTATIC com/project/extensions/ObservableExtensionsKt.observeOnMainThread (Lrx/Observable;)Lrx/Observable;
NEW com/project/package/SomeActivity$getDataFor$2
DUP
ALOAD 0
INVOKESPECIAL com/project/package/SomeActivity$getDataFor$2.<init> (Lcom/project/package/SomeActivity;)V
CHECKCAST rx/functions/Action1
NEW com/project/package/SomeActivityKt$sam$Action1$22181393
DUP
ALOAD 0
LDC "Fetching something list failed"
ICONST_0
ANEWARRAY java/lang/Object
INVOKESTATIC com/project/extensions/ActivityErrorHandlingExtensionsKt.defaultOnError (Landroid/app/Activity;Ljava/lang/String;[Ljava/lang/Object;)Lkotlin/jvm/functions/Function1;
DUP
IFNONNULL L16
POP
POP2
ACONST_NULL
GOTO L17
L16
INVOKESPECIAL com/project/package/SomeActivityKt$sam$Action1$22181393.<init> (Lkotlin/jvm/functions/Function1;)V
L17
CHECKCAST rx/functions/Action1
L18
LINENUMBER 165 L18
INVOKEVIRTUAL rx/Observable.subscribe (Lrx/functions/Action1;Lrx/functions/Action1;)Lrx/Subscription;
POP
L19
LINENUMBER 170 L19
RETURN
L20
LOCALVARIABLE this Lcom/project/package/SomeActivity; L0 L20 0
LOCALVARIABLE id Ljava/lang/String; L0 L20 1
MAXSTACK = 7
MAXLOCALS = 2
您可以發佈「工具 - > Kotlin - >顯示Kotlin字節碼」的問題活動的輸出嗎? –
@VyacheslavGerasimov請參閱更新。我發佈了'getDataFor'字節碼。讓我知道如果你需要更多,因爲我不想花費全天混淆所有2.5k行字節代碼:) –
是否有字節碼中的任何類名稱爲com/project/package/SomeActivityKt $ sam $ Action1 $ 22181393' ? 我想它應該爲您傳遞給訂閱方法的lambda生成。我的理論,它可能會產生一個錯誤的名稱。 –