• 我们在开发android应用的时候,如果依赖了很多三方库,应该会遇到65535放法数超限的问题,比如使用Android Studio进行构建apk的时候失败了,并报出如下错误日志

    AGPBI: {"kind":"error","text":"Cannot fit requested classes in a single dex file (# methods: 102169 > 65536)","sources":[{}],"tool":"D8"}
    com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
    The number of method references in a .dex file cannot exceed 64K.
    Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.htmlat com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:132)at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:119)at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:102)at com.android.build.gradle.internal.tasks.DexMergingTaskRunnable.run(DexMergingTask.kt:445)at com.android.build.gradle.internal.tasks.Workers$ActionFacade.run(Workers.kt:348)at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:50)at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:47)at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1$1.create(NoIsolationWorkerFactory.java:65)at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1$1.create(NoIsolationWorkerFactory.java:61)at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:98)at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.execute(NoIsolationWorkerFactory.java:61)at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    Cannot fit requested classes in a single dex file (# methods: 102169 > 65536)at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:56)at org.gradle.workers.internal.DefaultWorkerExecutor$3.call(DefaultWorkerExecutor.java:215)at org.gradle.workers.internal.DefaultWorkerExecutor$3.call(DefaultWorkerExecutor.java:210)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)at java.lang.Thread.run(Thread.java:748)
    Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to completeat com.android.tools.r8.utils.O.a(:65)at com.android.tools.r8.D8.run(:11)at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:117)
    Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete... 34 more
    Caused by: com.android.tools.r8.utils.b: Error: null, Cannot fit requested classes in a single dex file (# methods: 102169 > 65536)at com.android.tools.r8.utils.y0.a(:21)at com.android.tools.r8.dex.K.a(:56)at com.android.tools.r8.dex.K$h.a(:5)at com.android.tools.r8.dex.b.b(:15)at com.android.tools.r8.dex.b.a(:38)
    Caused by: com.android.tools.r8.utils.b: Error: null, Cannot fit requested classes in a single dex file (# methods: 102169 > 65536)at com.android.tools.r8.D8.d(:87)at com.android.tools.r8.D8.b(:1)at com.android.tools.r8.utils.O.a(:30)... 36 moreExecution failed for task ':app:mergeDexDebug'.
    > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: The number of method references in a .dex file cannot exceed 64K.Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html* Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
  • 这个问题很好解决的,只需要在build.gradle中配置支持多dex参数
    android {...defaultConfig {    ...multiDexEnabled true//解决方法数超65536限制问题}
    }
  • 然后再自己的Application里重写attachBaseContext(),加入MultiDex.install(context)即可
    ...import androidx.multidex.MultiDex;public class MyApplication extends Application {@Overrideprotected void attachBaseContext(Context context) {MultiDex.install(context);super.attachBaseContext(context);}
    }
    
  • 然后将自己的MyApplication注册到AndroidManifest.xml中
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.xx.xx"><applicationandroid:name="com.xx.xx.MyApplication"></application>
    </manifest>
  • 通过Android Studio处理65535放法数超限的问题是很好解决的,如果我们是逆向开发,比如有一个游戏应用接入了我们的SDK,给了一个apk给我们,我们需要拿到这个apk替换掉我们SDK的代码,并加入一些其他的插件SDK代码,我们应该怎么办呢
  • 首先接入我们SDK的应用不管他们出包的时候是否有放法数超限的问题,都进行上述处理65535放法数超限的解决方案去处理,这样处理过后,当我们合并到apk中的代码如果超限制了,也不用在合并的时候在Application里面去加入 MultiDex.install(context)了,没有超放法数也不会有什么影响
  • 合并代码的时候需要将母包通过apktool进行解析,然后将旧的代码或资源删除,然后加入新的代码和资源,加入新的代码就会引入65535放法数超限的问题,因为一个dex文件最多只能有65535个方法,多了的话,运行时会奔溃,合并的策略有多种,下面我们来具体说下吧
  • 方案一:直接合并到第一个smali文件夹中,然后对这个smali文件中的smali代码文件进行遍历计算它的方法数,当即将超过限制的放法数(最大方法数可以自己定义大小,不一定是65535,最好方法数不要太满了)后,就进行分包,比如分了一个smali_classes2,但是如何计算samli中的方法数呢,这个就需要去研究下smali的语法了,smali类里面的方法都是.method开头的,可以计算.method的个数来确定一个smali文件的方法数
  • 方案二:将需要合并的SDK代码文件,在生成smali文件的时候,就将其方法数算出来,比如我们合并一个apk、aar、jar等可以通过第三方开源dex-method-counts工具计算得到里面的方法数,也可以使用Android SDK自带的dexdump工具执行命令dexdump -f classes.dex | findstr method_ids_size 得到,dexdump工具位于sdk的build-tools/28.0.3下。得到方法数后就保存起来,下次合并的时候就不用再计算了,接着我们遍历解析后母包的samli目录,如果只有smali一个文件,就创建一个smali_classes2目录,然后将SDK的smali合并进去,并记录当前的方法数,这样一个一个进行合并,直到下一个SDK的放法数+待合并的smali目录放法数大于限制数,再创建一个smali_classesX,这样循环合并下去,保证新增的smali目录不超限制,这样有个缺点就是某些smali目录可能放法数不是很多,母包自带的第一个也没有利用起来,但是这个合并的效率很高,不用遍历每个smali代码文件去计算方法数,有点简单粗暴
    H:\Sdk\build-tools\28.0.3>dexdump -f classes.dex | findstr method_ids_size
    method_ids_size     : 1388
  • 虽然我们合并代码的多dex问题解决了,但是还有一个问题就是,我们在运行的时候可能会出现找不到类的异常ClassNotFindException,程序一运行就奔溃,上面我们不是已经配置了MultiDex.install(context);吗,原因很简单,就是我们的MyApplication 也许继承的是我们SDK的Application,而我们的Application也可能会集成其他的Application,而合并SDK里面的代码可能不在第一个dex里面,这时候我们就需要将MyApplication继承的父类,或者父类的父类找到,然后合并到第一个dex中去
  • 首先我们需要解析AndroidManifest.xml 文件得到里面配置的Application类路径,然后定位到smali代码文件中去,然后去查找其父类,如果父类不在第一个smali目录中则移动到一个smali目录中,接着再看移动的这个Application类的父类,一直寻找、移动下去,直到父类是java/lang/Object,就结束了。这样就能保证运行是不会报ClassNotFindException了
  • 对于逆向开发的多dex超65535放法数问题,我们只是讨论了一些可行的方案,大家可以自己手动去实现,也许还有更好的方法

Android 的65535放法数超限问题解决方案-AS方式、apk解析合并多dex、smali文件问题相关推荐

  1. 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

    文章目录 一.65535 方法数限制和 MultiDex 配置 二.多 DEX 加载引入 三.PathClassLoader 类加载源码分析 四.BaseDexClassLoader 类加载源码分析 ...

  2. React Native Android启动白屏的一种解决方案下

    React Native Android启动白屏的一种解决方案下 参考文章: (1)React Native Android启动白屏的一种解决方案下 (2)https://www.cnblogs.co ...

  3. android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)

    android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本) 参考文章: (1)android SQLite 批量插入数据慢的解决方案 (针对于不同的andro ...

  4. React Native Android启动白屏的一种解决方案上

    React Native Android启动白屏的一种解决方案上 参考文章: (1)React Native Android启动白屏的一种解决方案上 (2)https://www.cnblogs.co ...

  5. android Button背景高度被拉伸问题--解决方案

    android Button背景高度被拉伸问题--解决方案 参考文章: (1)android Button背景高度被拉伸问题--解决方案 (2)https://www.cnblogs.com/slys ...

  6. android开发出现No Launcher activity found!解决方案

    android开发出现No Launcher activity found!解决方案 参考文章: (1)android开发出现No Launcher activity found!解决方案 (2)ht ...

  7. Android软键盘遮挡的四种解决方案

    Android软键盘遮挡的四种解决方案 参考文章: (1)Android软键盘遮挡的四种解决方案 (2)https://www.cnblogs.com/jerehedu/p/4194125.html ...

  8. android系统性能优化(63)---Android APP 卡顿问题分析及解决方案

    Android APP 卡顿问题分析及解决方案 用户对卡顿的感知, 主要来源于界面的刷新. 而界面的性能主要是依赖于设备的UI渲染性能. 如果我们的UI设计过于复杂, 或是实现不够友好,计算绘制算法不 ...

  9. 这也许是Android一句话权限适配的更优解决方案

    SoulPermission Android一行代码权限的更优解决方案: 解耦Activity和Fragment.不再需要Context.不再需要onPermissionResult 内部涵盖版本判断 ...

最新文章

  1. swift 和 oc中检测textfield是否输入数字
  2. boost::geometry::strategy::transform::matrix_transformer用法的测试程序
  3. C/C++制作人机猜拳小游戏
  4. Centos7忘记密码——转
  5. 屏幕适配 percent_库的扩展
  6. 瓜子二手车:急招IoT架构师,相当阿里P9
  7. 【思路】2021年第十四届“认证杯“数学中国数学建模国际赛(小美赛)思路
  8. matlab中单相整流器,应用Matlab仿真单相PWM整流器的一种简单方法
  9. html5 main form 结合,web组件之表单(HTML5)
  10. bzoj 3772 :精神污染 线段树+打标记 or 主席树
  11. linux中IGV的运行,科学网—使用UCSC和IGV查看reads在基因组上分布情况 - 熊朝亮的博文...
  12. 不一样的课程表,不一样的Excle--用Excle进行设计(42):排序所演绎的数据逻辑
  13. 单身狗福音:钢铁直男也可以用AI歌曲俘获女友芳心!
  14. Springboot整合Spring Data JPA
  15. 出书最多--map值排序
  16. electron exec 神坑
  17. Paper intensive reading (十三):Removing batch effects in analysis of expression microarray data
  18. 由浅入深的前端面试题 和矫情的“浪漫主义”诗句
  19. FileLoadException: 未能加载文件或程序集.............或它的某一个依赖项。需要强名称程序集。...
  20. 6.3 图解BERT模型:从零开始构建BERT

热门文章

  1. JointJS官方API的个人整理
  2. Web服务器控件和HTML控件区别
  3. 数据结构专题—计算机中常用的数据结构
  4. webp文件怎么改成jpg?
  5. 大连确定今年道路交通管理10件实事
  6. webserveice搭建
  7. DSFormer: A Dual-domain Self-supervised Transformer for acc Multi-contrast MRI Re---文章阅读记录
  8. 如何学习IPv6安全
  9. (三)测试工具-3 adb安装卸载apk+清除数据
  10. [SECURITY]--01