3

最近,當我在家用我的電腦用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

  • 刪除buildapp/build迪爾斯

  • 在項目的根目錄中刪除.gradle DIR

  • Android 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 
+0

您可以發佈「工具 - > Kotlin - >顯示Kotlin字節碼」的問題活動的輸出嗎? –

+0

@VyacheslavGerasimov請參閱更新。我發佈了'getDataFor'字節碼。讓我知道如果你需要更多,因爲我不想花費全天混淆所有2.5k行字節代碼:) –

+0

是否有字節碼中的任何類名稱爲com/project/package/SomeActivityKt $ sam $ Action1 $ 22181393' ? 我想它應該爲您傳遞給訂閱方法的lambda生成。我的理論,它可能會產生一個錯誤的名稱。 –

回答

0

我幾個星期前,碰到了類似的問題。這基本上是我做過什麼,以避免ClassNotFoundException,在我的情況是由於Multidex「配置」更新Android工作室,gradle產出等

  1. 添加compile 'com.android.support:multidex:1.0.1'到依賴項列表中的應用程序文件的gradle後。
  2. 從您的應用程序類的onCreate()方法刪除Multidex.install(this);並添加應用程序類以下內容:

    @Override 
    protected void attachBaseContext(Context context) { 
        super.attachBaseContext(context); 
        MultiDex.install(this); 
    } 
    

我更新版本的Gradle,等以後得到了錯誤,所以請確保您所有的東西都是最新的。

希望它有幫助。

+0

我不會在'onCreate()'中調用'Multidex.install(this)',因爲我的'App'類從'MultiDexApplication'類繼承了這個行爲('attachBaseContext'已經在那裏實施)。所以我只添加了覆蓋(可能是多餘的)。不幸的是,它根本沒有幫助。它仍然在'SomeActivity'中崩潰(這不是在我的應用程序中啓動的第一個,順便說一句)。 –

相關問題