Twitter Fabric +MultiDex 导致 NoClassDefFoundError

Twitter Fabric +MultiDex causes NoClassDefFoundError

我在我的项目中启用了 Multidex 支持,它在 Android 5.0 及更高版本上运行良好,但是当我开始使用 Android 4.3 及以下版本测试我的应用程序时,它开始给我 NoClassDefFoundError TwitterConfig

我无法禁用 Multidex 支持。我不明白为什么我会遇到这个问题。试图在网上找到解决方案,但没有帮助。

这是我得到的异常。

java.lang.NoClassDefFoundError: com.twitter.sdk.android.core.TwitterAuthConfig
        at com.twitter.sdk.android.core.TwitterAuthConfig.<clinit>(TwitterAuthConfig.java:39)
        at MyApplication.onCreate(MyApplication.java:46)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4702)
        at android.app.ActivityThread.access00(ActivityThread.java:168)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1389)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5493)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
        at dalvik.system.NativeStart.main(Native Method)

这是我的 app.gradle

    buildscript {
    repositories {
        maven { url 'https://maven.fabric.io/public' }
    }

    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }
 }

    apply plugin: 'com.android.application'
    apply plugin: 'io.fabric'

  repositories {
    maven { url 'https://maven.fabric.io/public' }
    mavenCentral()

  }

   android {
    packagingOptions {
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE.txt'
    }
    compileSdkVersion 22
    buildToolsVersion "23.0.0 rc3"

    defaultConfig {            
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dexOptions {
        javaMaxHeapSize "2g"
    }

}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'       
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.android.support:design:22.2.1'
    compile 'com.android.support:recyclerview-v7:22.2.1'
    compile 'com.android.support:cardview-v7:22.2.1'
    compile 'com.android.support:support-v4:22.2.1'
    compile project(':MPChartLib')
    compile 'com.facebook.android:facebook-android-sdk:4.6.0'
    compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') {
        transitive = true;
    }
    compile('com.twitter.sdk.android:twitter:1.8.0@aar') {
        transitive = true;
    }
}

这是我在 MyApplication class 中的 Twitter 代码。

@Override
public void onCreate() {
    super.onCreate();

    //Configure twitter using Twitter key and Secret Key
    TwitterAuthConfig authConfig =
            new TwitterAuthConfig(TWITTER_KEY,
                    TWITTER_SECRET);

    // add functionalities which we are using with Fabric
    Fabric.with(this, new Crashlytics(), new Twitter(authConfig));

    FacebookSdk.sdkInitialize(getApplicationContext());
    // Initialize the SDK before executing any other operations,
    // especially, if you're using Facebook UI elements.

}

甚至我也尝试了 解决方案,但没有帮助。

感谢任何提示或参考。

Multidex 支持 Android 5.0 及更高版本

Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files. ART performs pre-compilation at application install time which scans for classes(..N).dex files and compiles them into a single .oat file for execution by the Android device. For more information on the Android 5.0 runtime, see Introducing ART.

这意味着您的应用可以在 API 级别 21 或更高级别上正常运行。

Android5.0

之前的 Multidex 支持

Versions of the platform prior to Android 5.0 use the Dalvik runtime for executing app code. By default, Dalvik limits apps to a single classes.dex bytecode file per APK. In order to get around this limitation, you can use the multidex support library, which becomes part of the primary DEX file of your app and then manages access to the additional DEX files and the code they contain.

所以,首先确保您导入了正确的依赖项,看来您已经导入了。

dependencies {
  compile 'com.android.support:multidex:1.0.1'
}

在您的清单中,将 multidex 支持库中的 MultiDexApplication class 添加到应用程序元素。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

或者,如果您的应用扩展 Application class,您可以覆盖 attachBaseContext() 方法并调用 MultiDex.install(this) 以启用 multidex

public void onCreate(Bundle arguments) {
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);
    ...
}

最后,您需要通过添加 multiDexEnabled true 更新您的 build.gradle 文件:

defaultConfig {  
        applicationId '{Project Name}'  
        minSdkVersion 15  
        targetSdkVersion 23  
        versionCode 1  
        versionName "1.0"  
        multiDexEnabled true  
    }  

希望对您有所帮助。

我通过手动将 fabric gradle 插件版本设置为较低版本“1.21.6”解决了这个问题。最新版本可能存在一些问题,在我的例子中是“1.23.0”。 (Fabric plugin version history)

所以我设置

dependencies {
        classpath 'io.fabric.tools:gradle:1.21.6'
    }

而不是

dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }