升级到 studio 3.0 使我的应用崩溃 dalvik.system.BaseDexClassLoader.findClass

Upgrade to studio 3.0 is crashing my app with dalvik.system.BaseDexClassLoader.findClass

这是在使用 android 4.4 从 studio 2.x 迁移到 studio 3.0 之后发生的。 Android 6 运行良好。 我用谷歌搜索了这个问题,但没有找到明确的回应。只有一个特定的应用程序有这种行为。我有其他的应用程序很好。

更新过程出了问题,但是什么?为什么它只影响 android 4.x?

我尝试了干净同步、重建、重启工作室、重启平板电脑、...

这是我的 gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    defaultConfig {
        applicationId "com.narb.test"
        minSdkVersion 18
        targetSdkVersion 24
        versionName '3.2'
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        versionNameSuffix '-9-nov-2017'
        multiDexEnabled true
        versionCode 53
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile files('libs/commons-net-3.5.jar')
    compile 'com.android.support:appcompat-v7:26.1.0'
    compile 'com.android.support:support-v4:26.1.0'
    compile 'com.google.android.gms:play-services-maps:10.0.1'
    testCompile 'junit:junit:4.12'
    compile 'org.jsoup:jsoup:1.10.3'
}

和 logcat:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.narb.test/com.narb.test.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.narb.test.MainActivity" on path: DexPathList[[zip file "/data/app/com.narb.test-29.apk"],nativeLibraryDirectories=[/data/app-lib/com.narb.test-29, /vendor/lib, /system/lib]]
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
     at android.app.ActivityThread.access0(ActivityThread.java:174)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:146)
     at android.app.ActivityThread.main(ActivityThread.java:5593)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
     at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.narb.test.MainActivity" on path: DexPathList[[zip file "/data/app/com.narb.test-29.apk"],nativeLibraryDirectories=[/data/app-lib/com.narb.test-29, /vendor/lib, /system/lib]]
     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:67)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
     at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2296)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470) 
     at android.app.ActivityThread.access0(ActivityThread.java:174) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:146) 
     at android.app.ActivityThread.main(ActivityThread.java:5593) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
     at dalvik.system.NativeStart.main(Native Method) 

和清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.narb.test">

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


    <application
        android:allowBackup="true"
        android:largeHeap="true"
        android:configChanges="keyboardHidden|screenSize"
        android:icon="@drawable/networksafe"
        android:label="test"
        android:logo="@drawable/networksafe"
        android:screenOrientation="portrait"
        android:supportsRtl="true"

        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".vpn.services"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_VPN_SERVICE">

            <intent-filter>
                <action android:name="android.Net.Services"/>
            </intent-filter>
        </service>
        <activity
            android:name=".Activities.Settings"
            android:windowSoftInputMode="stateHidden" />
        <activity android:name=".Activities.About" />
        <activity android:name=".Activities.History" />

        <service
            android:name=".Socket"
            android:exported="false" />

        <service
            android:name=".ServiceMonitoring"
            android:exported="false" />


        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity android:name=".Activities.RateMe"></activity>
    </application>

</manifest>

运行 Gradle 清理命令然后执行文件 -> 使缓存无效并重新启动。对我来说它解决了问题

崩溃是由于 build.gradle 中的这一行:

multiDexEnabled 真

一旦我删除了这一行,崩溃就消失了。

我不知道为什么2.3原来放了这一行,但可以肯定的是studio 3.0让sdk 18及以下版本崩溃了。

在您的情况下,如果您不需要 multidex,那么禁用它是正确的解决方案。如果您将来需要它,请按照下面链接的说明使用 MultiDexApplication。

对于上下文,有两种类型的 multidex,即传统的和本机的。对于设备 API 21 及以上,平台只是直接从 APK 中读取多个 dex 文件。

对于 API 21 之前的设备,有 multidex 支持库可以修补 classloader 以添加额外的 dex 文件作为应用程序的一部分 class。在此之前可以加载的任何内容都需要在主 dex 中,并且您需要使用 MultiDexApplication(或 subclass,或从您的应用程序 onAtttachBaseContext 调用 MultiDex.install(this))

Android studio 3.0 切换到为调试构建创建最小主 dex,即只在主 dex 中保留最小的文件集。这是为了提高构建性能并使这些崩溃可重现,而不是运气 class 是否包含在主 dex 中。

在您的情况下,您的应用程序适合 2.3 中的一个 dex,但在 3.0 中具有新的最小主 dex 行为,class 不在主 dex 中。但是,因为您没有使用 MultiDexApplication,classloader 永远不会打补丁,所以无法加载辅助 dex 文件中的 classes。

有关详细信息,请参阅 https://developer.android.com/studio/build/multidex.html#mdex-gradle