Android 多重索引后的NoClassDefFoundError

Android 多重索引后的NoClassDefFoundError,android,android-multidex,Android,Android Multidex,在得到65k方法限制后,我实现了多重索引。在实现多重索引后,我能够运行应用程序。但是现在我从外部jar中得到了我使用的一个类的错误NoClasDefFoundError 这是我的档案-- 依赖项{ 编译项目(':pull to refresh') 编译文件树(目录:“libs”,包括:“*.jar”) 编译项目(':gson-2.2.2') 编译文件('libs/android support multidex.jar') 编译'com.android.support:appcompat-v7:

在得到65k方法限制后,我实现了多重索引。在实现多重索引后,我能够运行应用程序。但是现在我从外部jar中得到了我使用的一个类的错误NoClasDefFoundError

这是我的档案--

依赖项{
编译项目(':pull to refresh')
编译文件树(目录:“libs”,包括:“*.jar”)
编译项目(':gson-2.2.2')
编译文件('libs/android support multidex.jar')
编译'com.android.support:appcompat-v7:21.0.0'
编译'com.google.android.gms:play services:6.1.71'
编译'com.android.support:support-v4:21.0.0'
}
安卓{
编译DK21版
buildToolsVersion'21.1.1'
包装选项{
排除“META-INF/LICENSE.txt”
排除“META-INF/NOTICE.txt”
}
源集{
主要{
manifest.src文件“AndroidManifest.xml”
java.srcDirs=['src']
resources.srcDirs=['src']
aidl.srcDirs=['src']
renderscript.srcDirs=['src']
res.srcDirs=['res']
assets.srcDirs=['assets']
}
//将测试移动到tests/java、tests/res等。。。
instrumentTest.setRoot('tests'))
//将生成类型移动到生成类型/
//例如,build-types/debug/java、build-types/debug/AndroidManifest.xml。。。
//这会将它们移出src/…下的默认位置,这将
//与主源集正在使用的src/冲突。
//应同时添加新的构建类型或产品风格
//通过类似的定制。
setRoot('build-types/debug')
setRoot('build-types/release')
}
德克斯选项{
preDexLibraries=false
}
后评价{
任务.匹配{
it.name.startsWith('dex'))
}.每个{dx->
如果(dx.additionalParameters==null){
dx.additionalParameters=['--multi-dex']
}否则{
dx.additionalParameters+='--multi-dex'`在此处输入代码`
}
}
}
}

我可以通过确保MultiDex.install行在调用super.attachBaseContext之后来修复此问题。如果在super.attach之前调用install,显然它没有正确注册但是,简单地更改应用程序类以扩展MultiDexApplication而不是application可能是更好的选择。

注意:扩展MultiDex应用程序后,您不再需要重写attachBaseContext并调用MultiDex.install(此)。如果您查看MultiDexApplication()的源代码,就会发现这个类的全部目的就是为您调用install


Google()的官方说明为您提供了MultiDexApplication()的文档这个页面包含了解决这个问题的多个选项的说明,但我第一次错过了,所以我相信其他很多人也会错过。

这发生在我们的一个Android项目中,该项目启用了多索引,并且已经正确设置(它在super.attachBaseContext(…)之后调用MultiDex.install)

它被追踪到一个私有的静态内部类,我们用它来实现按需初始化持有者惯用设计模式(惰性加载的单例)。显然,该类没有包含在主dex文件中,这导致了NoClassDefFoundError


我们最终只是将singleton类作为一个枚举。

提供源代码如何实现多重索引?我也遇到了类似的问题。要添加更多详细信息:我在我的应用程序子类的
attachBaseConext()
中调用
MultiDex.install()
,我可以在日志中看到输出,指示它正在安装,并找到classes2.dex。我可以正常运行应用程序的大部分——它不会崩溃,因为我的应用程序子类引用的类丢失了——但是当它调用辅助索引中的第三方库方法时,我得到了NoClassDefFoundError。我没有在dx调用中使用
--main-dex-list
。很抱歉第二条评论;我不能再编辑第一个。事实证明,多重索引不能很好地用于仅通过JNI调用的Java代码。即使使用
--main dex list
将所有从本机调用的类保存在一个dex中,也不会触发重写这些类方法中的调用站点。您必须将每个代码路径下引用的每个类添加到主索引列表中才能使其工作,这可能会破坏使用multidex的目的,即使是库中的内部API更改,它也非常脆弱。感谢回复@icodestuff,但是如何将每个代码路径下引用的类添加到主索引列表中,以使其工作
dependencies {
    compile project(':pull-to-refresh')
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':gson-2.2.2')
    compile files('libs/android-support-multidex.jar')
    compile 'com.android.support:appcompat-v7:21.0.0'
    compile 'com.google.android.gms:play-services:6.1.71'
    compile 'com.android.support:support-v4:21.0.0'
}


android {
    compileSdkVersion 21
    buildToolsVersion '21.1.1'

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
    dexOptions {
        preDexLibraries = false
    }
    afterEvaluate {
        tasks.matching {
            it.name.startsWith('dex')
        }.each { dx ->
            if (dx.additionalParameters == null) {
                dx.additionalParameters = ['--multi-dex']
            } else {
                dx.additionalParameters += '--multi-dex'`enter code here`
            }
        }
    }
}