Android学习之路------解决dex方法数超过65535的问题

前言

今天使用AS编译一个demo时,因为引用了android原生jar包class.jar和其他一些jar,在构建编译时出现以下错误:
Execution failed for task ':hdmiindemo:transformClassesWithDexForDebug'.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

然后网上找了一下资料普遍的方法是在build.gradle中加入以下两段代码

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        //加上这句话
        multiDexEnabled true


    }

}

dependencies {

    //加上这句话
    compile 'com.android.support:multidex:1.0.0'
}

这时候编译完成,可以正常生成apk,但是在运行时又报如下错误:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.hdmiindemo/com.example.hdmiindemo.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.example.hdmiindemo.MainActivity" on path: DexPathList[[zip file "/data/app/com.example.hdmiindemo-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.hdmiindemo-1, /system/lib, /vendor/lib, /system/lib/egl]]
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread.access$800(ActivityThread.java:135)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
[28:10:45:10]E/AndroidRuntime(15505):        at android.os.Handler.dispatchMessage(Handler.java:102)
[28:10:45:10]E/AndroidRuntime(15505):        at android.os.Looper.loop(Looper.java:136)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread.main(ActivityThread.java:5017)
[28:10:45:10]E/AndroidRuntime(15505):        at java.lang.reflect.Method.invokeNative(Native Method)
[28:10:45:10]E/AndroidRuntime(15505):        at java.lang.reflect.Method.invoke(Method.java:515)
[28:10:45:10]E/AndroidRuntime(15505):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:815)
[28:10:45:10]E/AndroidRuntime(15505):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
[28:10:45:10]E/AndroidRuntime(15505):        at dalvik.system.NativeStart.main(Native Method)
[28:10:45:10]E/AndroidRuntime(15505): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.hdmiindemo.MainActivity" on path: DexPathList[[zip file "/data/app/com.example.hdmiindemo-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.hdmiindemo-1, /system/lib, /vendor/lib, /system/lib/egl]]
[28:10:45:10]E/AndroidRuntime(15505):        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
[28:10:45:10]E/AndroidRuntime(15505):        at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
[28:10:45:10]E/AndroidRuntime(15505):        at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
[28:10:45:10]E/AndroidRuntime(15505):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
[28:10:45:10]E/AndroidRuntime(15505):        ... 11 more
[28:10:45:10]W/ActivityManager( 1458):   Force finishing activity com.example.hdmiindemo/.MainActivity


最后在更改一下manifest,在application下加入

android:name="android.support.multidex.MultiDexApplication">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true" android:theme="@style/AppTheme"
        android:name="android.support.multidex.MultiDexApplication">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

最终可以正常运行

关于64 k引用限制 Android应用程序(APK)在Dalvik可执行文件的形式包含可执行的字节码文件(DEX)文件,其中包含已编译的代码来运行你的应用程序。Dalvik可执行规格限制一个Dex文件包含65536个方法:包括Android框架方法、Library方法的总、和你自己的代码方法。因为65536等于64×1024,这一限制被称为“64k引用限制”。 这个极限就要求我们配置应用程序的构建过程,需要生成多个DEX文件,所以称为multidex 配置。 分析原因与注意事项 解决方法Android 5.0及以上系统和5.0以下系统怎么做。客官们不要着急,先看我一个个分析原因,毕竟我要装下逼哈哈。 一、Android 5.0以下的版本 Android 5.0(API leve 21)之前的系统使用Dalvik执行应用程序代码。默认情况下,Dalvik限制一个apk只有一个Dex文件。为了绕过这个限制, 我们可以使用multidex support library,它成为我们APK的主要DEX文件的一部分,负责管理我们APK访问其他DEX文件和代码。 注意: 如果咱的项目minSdkVersion是20或更低,运行到Android 4.4(API leve 20)或者更低版本的设备上时需要禁用AndroidStudio的即时运行 二、Android 5.0和更高版本 Android 5.0(API leve 21)和更高的系统使用runtime是ART ,原生支持从应用的apk文件加载多个DEX文件。ART在安装应用时预编译应用程序,会扫描多个classes(..N).dex文件编译成一个.oat的文件。更多Android5.0 runtime的更多信息,请参见即时运行-instant-run。 注意: 如果你使用即时运行 , AndroidStudio自动配置你的应用程序,你应用程序的minSdkVersion应该设置为21或更高。因为即时只工作在你APP的Debug版本,你任然需要配置你的release版本构建时用multidex避免64k的限制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值