首页 > 编程语言 >Android_关于程序产生 65535 (64K)的解决办法

Android_关于程序产生 65535 (64K)的解决办法

时间:2023-04-18 11:36:14浏览次数:39  
标签:java DexMerger 64K dx 65535 Android Main com android


随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的错误:

UNEXPECTED TOP-LEVEL EXCEPTION:  
java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536  
at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:501)  
at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:282)  
at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:490)  
at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)  
at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)  
at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)  
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)  
at com.android.dx.command.dexer.Main.run(Main.java:230)  
at com.android.dx.command.dexer.Main.main(Main.java:199)  
at com.android.dx.command.Main.main(Main.java:103)
trouble writing output: 
Too many field references: 131000; max is 65536. 
You may try using –multi-dex option.

这错误的意思是说,你的应用中的Dex文件方法数超过了最大值 65536的上限值,简单来说, 超过了应用内的方法数限制,

在Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。因为Android系统使用Dalvik虚拟机,所以需要把使用Java Compiler编译之后的class文件转换成Dalvik能够执行的class文件。这里需要强调的是,Dex和Jar一样是一个归档文件,里面仍然是Java代码对应的字节码文件。当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。但是在早期的Android系统中,DexOpt有一个问题,也就是这篇文章想要说明并解决的问题。DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对低版本的Android系统做兼容

这种问题官方也关注到了,为了解决这一问题,提出了通过multidex包进行多dex编译的方法:
第一步: 首先添加如下内容到graldr中去.

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        minSdkVersion 14
        targetSdkVersion 21
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = []
        }
        dx.additionalParameters += '--multi-dex' // enable multidex
    }
}

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

第二步:覆写Application类

如果你的工程中已经含有Application类,那么让它继承android.support.multidex.MultiDexApplication类,
如果你的Application已经继承了其他类并且不想做改动,那么还有另外一种使用方式,覆写attachBaseContext()方法。

import android.support.multidex.MultiDex;

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

至此, 已经完成了, 若代码函数超过65535, 就会生成多个dex文件,不会再报错,可以去测试一下,至于其他会出现的问题我会单独列博客说明

标签:java,DexMerger,64K,dx,65535,Android,Main,com,android
From: https://blog.51cto.com/u_16077105/6202741

相关文章

  • android 抽屉的一些小问题
    1、如果给SlidingDrawer添加android:clickable="true"则在抽屉活动的一块区域屏幕不会响应其他点击事件,即使抽屉式关闭的。 2、android:handle="@+id/handle"里面的handle是SlidingDrawer标签里面你要作为抽屉图标的view的id。android:content="@+id/all_run_app"中的all_run_app......
  • android bitmap oom 处理
    如果activity结束了就  bitmap.recycle(); 如果涉及到重复加载按钮的:if(bitmap!=null&&!bitmap.isRecycled()){bitmap.recycle();bitmap=null;//这里最好加上这一句Log.e("freeBitmap","=============recyclebitmap=======");}......
  • 如何让Android支持GIF图片
    publicclassSampleViewextendsView{privateMoviemMovie;privateBitmapmBitmap;privateCanvasmCanvas;privatelongmMovieStart;privatebyte[]streamToBytes(InputStreamis){ByteArrayOutputStreamos=newByteArrayOutp......
  • 理解Android系统的进程间通信原理(一)----RPC中的代理模式
    理解Android系统的进程间通信原理(一)----RPC中的代理模式Android系统中的进程间通信是通过一个轻量级的RPC(RemoteProcedureCall远程进程调用)和AIDL(AndroidInterfaceDefininationLanguage)规范来生成两个进程之间可以相互访问的代码。其中RPC是以接口方式来实现,客户端与被......
  • Android Handler 知识点
    Android面试必问的Handler知识点一叶飘舟于 2020-12-0312:03:10 发布547 收藏 9 版权前言在Android中,Handler是贯穿于整个应用的消息机制,在面试中出现的概率为:100%在这篇文章里,我将带你梳理Handler的使用攻略&设计原理。追求简单易懂又不失深度......
  • 《花雕学AI》20:ChatGPT使用之体验评测AI EDU的网页版+桌面端+Android+App store组合
    最近准备出门,要去新疆哈密参加活动,一直在寻找手机上可用的AI移动端。昨天在网上偶然找到了AIEDU(这个不是MSRA创立的人工智能开源社区),其链接是:https://ai.aigcfun.com,今天就尝试做个相关体验与学习的记录。打开首页如下:  引言:人工智能聊天机器人ChatGPT是一种基于GPT-......
  • Android studio 中fragment 的简单应用
    在AndroidStudio中,Fragment是一种可重用的UI组件,它代表了Activity中的一部分界面。它类似于Activity,但是可以被添加、删除和替换,同时可以与其他Fragment组合在一起形成更复杂的UI界面。通常情况下,Activity由多个Fragment组成,每个Fragment都有自己的布局和功能,可......
  • Android深入学习之LayoutInflater类和ViewBinding
    在build.gradle(Module)中添加viewBinding元素后,Android会自动给模块中的每个XML布局文件生成一个相应的Binding类,该Binding类名称为XML布局文件驼峰式大写+Binding后缀。以如下所示的activity_welcome.xml文件为例,对应的ActivityWelcomeBinding.java的源代码如下所示。<?xmlv......
  • Android入门教程_废弃
    没意思,不想写了... 目录一,Android介绍Android概述什么是AndroidAndroid开发优势Android的特性可以开发什么appAndroid手机安装包apkAndroid架构https://www.runoob.com/android/android-architecture.html学习安卓需要具备哪些知识(PS+UI(优秀软件:墨刀-万兴科技......
  • Android Studio调用高德地图api
    一.搜索高德开放平台,进行注册并登录,进入到自己的控制台,打开应用管理下的我的应用,点击创建新应用。1.关于获取发布版安全码SHA1的过程如下:    打开AndroidStudio下方的Terminal,并自行找到.android在电脑中的位置,找到了之后,按照下图所示:   之后执行keytool-lis......