内容简介:本篇主要介绍 Android 应用异常捕获、DEX 方法数越界、动态加载技术以及反编译相关的知识点。通过设置完整的 CrashHandler 示例可以点击
本篇主要介绍 Android 应用异常捕获、DEX 方法数越界、动态加载技术以及反编译相关的知识点。
使用 CrashHandler 来获取应用的 crash 信息
通过设置 Thead.setDefaultUncaughtExceptionHandler(handler)
的默认异常处理器就可以实现应用的异常捕获:
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { defaultUncaughtExceptionHandler = eh; }
完整的 CrashHandler 示例可以点击 这里
使用 multidex 来解决方法数越界
Android 中单个 DEX 文件内可引用的方法总数限制在 65,536,如果方法数超过了最大值,那么编译会报 DexIndexOverflowException
。此外,在 Android 2.x 版本上由于 LinearAlloc 缓冲区分配过小也有可能导致安装失败。
解决 64K 限制
使用 Google 2014 年提出 multidex 解决方案,步骤如下:
-
如果
minSdkVersion
设置为 21 或更高值,只需在模块级build.gradle
文件中将multiDexEnabled
设置为true
即可,如下所示:android { defaultConfig { ... minSdkVersion 21 targetSdkVersion 28 multiDexEnabled true } ... }
-
如果
minSdkVersion
低于 21,除了将multiDexEnabled
设置为true
,还需要添加对 multidex jar 包的依赖:dependencies { compile 'com.android.support:multidex:1.0.3' }
-
同时还需要修改代码以适配 multidex,以下方式三选一:
-
在
AndroidManifest.xml
中指定Application
为MultiDexApplication
:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application android:name="android.support.multidex.MultiDexApplication" > ... </application> </manifest>
-
让应用的
Application
继承MultiDexApplication
:public class MyApplication extends MultiDexApplication { ... }
-
此外,还可以重写
ttachBaseContext
方法:public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
-
声明主 DEX 文件中需要的类
为 Dalvik 分包构建每个 DEX 文件时,构建 工具 会执行复杂的决策制定来确定主 DEX 文件中需要的类,以便应用能够成功启动。如果启动期间需要的某个类未在主 DEX 文件中提供,那么应用将崩溃并出现错误 java.lang.NoClassDefFoundError
。针对这种情况,我们可以使用构建类型中的 multiDexKeepFile
或 multiDexKeepProguard
属性声明它们,以手动将这些类指定为主 DEX 文件中的必需项,当然《Android 开发艺术探索》中提到的 --main-dex-list
方式也是同样的原理。
-
multiDexKeepFile 属性
创建一个名为
multidex-config.txt
的文件,如下所示:com/example/MyClass.class com/example/MyOtherClass.class
然后在构建类型声明该文件即可:
android { buildTypes { release { multiDexKeepFile file 'multidex-config.txt' ... } } }
-
multiDexKeepProguard 属性
建一个名为
multidex-config.pro
的文件,如下所示:-keep class com.example.MyClass -keep class com.example.MyClassToo
如果想要指定包中的所有类,文件可以如下所示:
-keep class com.example.** { *; }
最后在构建类型声明该文件:
android { buildTypes { release { multiDexKeepProguard 'multidex-config.pro' ... } } }
Multidex 方案可能带来的问题:
- 应用启动速度会降低。因为应用启动的时候会加载额外的 DEX 文件,所以要尽量避免生成较大的 DEX 文件;
- 由于 Dalvik LinearAlloc 的 bug,可能导致采用 multidex 方案的应用无法在 Android 4.0 以前的手机上运行,当然这种现象极少遇到。
Android 的动态加载技术
动态加载技术(插件化技术),即通过插件化减轻应用的内存和 CPU 占用,还可以在不发布新版本的情况下更新某些模块。不同的插件化方案各有特色,但是都需要解决三个基础性问题:资源访问,Activity 生命周期管理和插件 ClassLoader 的管理。
资源访问
宿主程序调起未安装的插件 apk,插件中凡是 R 开头的资源都不能访问了,因为宿主程序中并没有插件的资源,通过 R 来访问插件的资源是行不通的。由于 Activity 的资源访问都是通过 ContextImpl 来完成的,它有两个方法 getAssets()
和 getResources()
,它们是用来加载资源的。 具体实现方式是通过反射,调用 AssetManager 的 addAssetPath
方法添加插件的路径,然后将插件 apk 中的资源加载到 Resources 对象中即可。
Activity 生命周期管理
管理 Activity 生命周期的方式各种各样,有两种常见的方式:反射方式和接口方式。反射方式就是通过反射去获取 Activity 的各个生命周期方法,然后在代理 Activity 中去调用插件 Activity 对应的生命周期方法即可。使用反射方式代码复杂,性能开销大。接口方式将 Activity 的生命周期方法提取出来作为一个接口,然后通过代理 Activity 去调用插件 Activity 的生命周期方法,这样就完成了插件 Activity 的生命周期管理。
插件 ClassLoader 的管理
为了更好地对多插件进行支持,需要合理地去管理各个插件的 DexClassLoader,这样同一个插件就可以采用同一个 ClassLoader 去加载类,从而避免了多个 ClassLoader 加载同一个类时所引起的类型转换错误。
更多信息可以参考开源项目 DL-Apk动态加载框架
反编译初步
三个常用的反编译工具如下:
- Apktool : https://ibotpeaches.github.io/Apktool/
- dex2jar : https://github.com/pxb1988/dex2jar
- JD-GUI : http://jd.benow.ca/
反编译流程:一种方式是将 apk 解压,提取出 classes.dex
文件,接着通过 dex2jar 反编译,然后通过 JD-GUI 打开反编译后的 jar 包。或者直接使用 apktool 对 apk 进行解包/二次打包,以及使用 jarsigner 完成 apk 的签名。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 分布式协调系统的ZK的技术理论剖析-综合组件环境实战
- Achronix与Mentor携手带来高等级逻辑综合(HLS)与FPGA技术之间的连接
- 面试小结之综合篇
- Jenkins 持续集成综合实战
- 笔记16:前端综合回顾篇
- 记一道 Java 综合面试题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java核心技术·卷 I(原书第10版)
[美] 凯.S.霍斯特曼(Cay S. Horstmann) / 周立新 等 / 机械工业出版社 / 2016-9 / CNY 119.00
Java领域最有影响力和价值的著作之一,由拥有20多年教学与研究经验的资深Java技术专家撰写(获Jolt大奖),与《Java编程思想》齐名,10余年全球畅销不衰,广受好评。第10版根据Java SE 8全面更新,同时修正了第9版中的不足,系统全面讲解了Java语言的核 心概念、语法、重要特性和开发方法,包含大量案例,实践性强。 一直以来,《Java核心技术》都被认为是面向高级程序员的经典教......一起来看看 《Java核心技术·卷 I(原书第10版)》 这本书的介绍吧!