第十三章 综合技术
2017-01-25 13:23
85 查看
13.1 使用CrashHandler来获取应用的Crash信息
(1). 应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的setDefaultUncaughtExceptionHandler方法!
defaultUncaughtHandler是Thread类的静态成员变量,所以如果我们将自定义的
UncaughtExceptionHandler设置给Thread的话,那么当前进程内的所有线程都能使用这个UncaughtExceptionHandler来处理异常了。
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) { Thread.defaultUncaughtHandler = handler; }
(2). 作者实现了一个简易版本的UncaughtExceptionHandler类的子类CrashHandler,CrashHandler的使用方法就是在Application的
onCreate方法中设置一下即可。
public class MyApp extends Application { private static TestApp sInstance; @Override public void onCreate() { super.onCreate(); sInstance = this; //在这里为应用设置异常处理,然后程序才能获取未处理的异常 CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(this); } public static TestApp getInstance() { return sInstance; } }
13.2 使用multidex来解决方法数越界
(1). 在Android中单个dex文件所能够包含的最大方法数是65536,这包含Android Framework、以来的jar以及应用本身的代码中的所有方法。如果方法书超过了最大值,那么编译会报错
DexIndexOverflowException。
有时方法数没有超过最大值,但是安装在低版本手机上时应用异常终止了,报错
Optimization failed。这是因为应用在安装的时候,系统会通过
dexopt程序来优化dex文件,在优化的过程中dexopt采用一个固定大小的缓冲区来存储应用中所有方法的信息,这个缓冲区是
LinearAlloc。LinearAlloc缓冲区在新版本的Android系统中大小是8MB或者16MB,但是在Android 2.2和2.3中却只有5MB,这种情况下dexopt就会报错导致安装失败。
(2). 如何解决方法数越界的问题呢? Google在2014年提出了简单方便的
multidex解决方案。在Android 5.0之前使用multidex需要引入
android-support-multidex.jar包,从Android 5.0开始,系统默认支持了multidex,它可以从apk中加载多个dex。Multidex方案主要针对AndroidStudio和Gradle编译环境。
使用Multidex的步骤:
1.在
build.gradle文件中添加
multiDexEnabled true
android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "com.multidextest" minSdkVersion 8 tartgetSdkVersion 22 versionCode 1 versionName "1.0" // enable multidex support multiDexEnabled true } }
2.添加对multidex的依赖
compile 'com.android.support:multidex:1.0.0'
3.在代码中添加对multidex的支持,这里有三种方案:
在AndroidManifest文件中指定Application为
MultiDexApplication
<application android:name="android.support.multidex.MultiDexApplication" ... </application>
让应用的Application继承自
MultiDexApplication
重写Application的
attachBaseContext方法,这个方法要先于
onCreate方法执行。
public class TestApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } }
采用上面配置之后,如果应用的方法数没有越界,那么Gradle并不会生成多个dex文件;如果方法数越界后,Gradle就会在apk中打包2个或者多个dex文件,具体会打包多少个dex文件要看当前项目的代码规模。在有些情况下,可能需要制定主dex文件中所要包含的类,这个可以通过
--main-dex-list选项来实现这个功能。
afterEvaluate { println "afterEvaluate" tasks.matching { it.name.startsWith('dex') }.each {dx -> def listFile = project.rootDir.absolutePath + '/app/maindexlist.txt' println "root dir:" + project.rootDir.absolutePath println "dex task found: " + dx.name if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' dx.additionalParameters += '--main-dex-list=' + listFile dx.additionalParameters += '--minimal-main-dex' } }
--multi-dex表明当前方法数越界时生成多个dex文件,
--main-dex-list指定了要在dex中打包的类的列表,
--minimal-main-dex表明只有
--main-dex-list所指定的类才能打包到主dex中。multidex的jar包中的9个类必须要打包到主dex中,其次不能再Application中成员以及代码块中访问其他dex中的类,否则程序会因为无法加载对应的类而中止执行。
(3). Multidex方案可能带来的问题:
1. 应用启动速度回降低,因为应用启动的时候会加载额外的dex文件,所以要避免生成较大的dex文件;
2. 需要做大量的兼容性测试,因为Dalvik LinearAlloc的bug,可能导致使用multidex的应用无法在Android 4.0以前的手机上运行。
13.3 Android的动态加载技术
(1). 动态加载技术又称插件化技术,将应用插件化可以减轻应用的内存和CPU占用,还可以在不发布新版本的情况下更新某些模块。不同的插件化方案各有特色,但是都需要解决三个基础性问题:资源访问、Activity生命周期管理和插件ClassLoader的管理。(2). 宿主和插件:宿主是指普通的apk,插件是经过处理的dex或者apk。在主流的插件化框架中多采用特殊处理的apk作为插件,处理方式往往和编译以及打包环节有关,另外很多插件化框架都需要用到代理Activity的概念,插件Activity的启动大多数是借助一个代理Activity来实现的。
(3). 资源访问:宿主程序调起未安装的插件apk,插件中凡是R开头的资源都不能访问了,因为宿主程序中并没有插件的资源,通过R来访问插件的资源是行不通的。Activity的资源访问是通过了
ContextImpl来完成的,它有两个方法
getAssets()和
getResources()方法是用来加载资源的。具体实现方式是通过反射,调用
AssetManager的
addAssetPath方法添加插件的路径,然后将插件apk中的资源加载到Resources对象中即可。
(4). Activity生命周期管理:有两种常见的方式,反射方式和接口方式。反射方式就是通过反射区获取Activity的各个生命周期方法,然后在代理Activity中调用插件Activity对应的生命周期方法即可。反射方式代码繁琐,性能开销大。接口方式将Activity的生命周期方法提出来作为一个接口,然后通过代理Activity去调用插件Activity的生命周期方法,这样就完成了插件Activity的生命周期管理。
(5). 插件ClassLoader的管理:为了更好地对多插件进行支持,需要合理地区管理各个插件的
DexClassLoader这样同一个插件就可以采用同一个ClassLoader去加载类,从而避免了多个ClassLoader加载同一个类时所引起的类型转化错误。作者插件化框架singwhatiwanna/dynamic-load-apk
13.4 反编译初步
(1). 使用dex2jar和jd-gui反编译apk以下是window下使用方法:
1. 更改 Android APK 文件的后缀名为ZIP。如:将 “androil_0.62.apk”修改为“androil_0.62.zip”,注意不要修改成了“androil_0.62.zip.apk”哦。
2. 使用解压缩工具将“androil_0.62.zip”解压。
3. 从解压缩的文件夹中将 classes.dex 文件复件到 dex2jar.bat 所在目录。
4. 运行 cmd 命令,进入 dex2jar.bat 所在的目录,输入
dex2jar.bat classes.dex即可生成
classes.dex.dex2jar.jar文件
5. 用 jd-gui 工具打开 classes.dex.dex2jar.jar 文件,即可看到源码。
6. 将 AndroidManifest.xml 文件放到 AXMLPrinter2.jar 所在目录,运行 cmd 命令,进入 AXMLPrinter2.jar 所在目录,输入
java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest.txt。
7. 打开 AndroidManifest.txt 文件,即可查看到源代码。
下载地址:
apktool
dex2jar
jd-gui
第十四章 JNI和NDK编程 请参考 Android进阶之路——NDK(一)和Android进阶之路——NDK(二)
相关文章推荐
- 杨树食叶害虫综合防治技术
- 基于EPON+EOC技术构建广电综合业务宽带接入网
- 第13章.综合技术
- DHTML技术综合演示---示例:下拉风格的菜单条
- 【实验】综合实验(VLAN间通信,ACL技术,DNS/WEB服务器架设,RIP路由)
- DHTML技术综合演示---示例:下拉风格的菜单条2--用表格封装的
- 常见云产品和云技术综合比较与分析
- 多种sql技术的综合应用(行转列、定制、批量数据产生)
- OCR识别技术在银行单证综合处理系统中的应用
- 不要去做技术高手,只去做综合素质高手!
- 【CCIE技术】WLAN安全技术综合分析详解概述
- 综合图形学算法及OpenGL技术开发一个小型图形软件系统
- [spring cloud学习4]综合使用spring cloud技术实现微服务
- mysql 综合技术点
- 360公司 2018校招 技术综合C卷在线考试 编程题
- Eclipse插件开发 学习笔记 PDF 第一篇到第四篇 免分下载 开发基础 核心技术 高级进阶 综合实例
- 我记录网站综合系统 -- 技术原理解析[2:C# 水印和验证码的制作]
- 我记录网站综合系统 -- 技术原理解析[4:我记录框架 路由系统]
- 我记录网站综合系统 -- 技术原理解析[8:ActionChecker流程]
- 网络综合布线系统与施工技术