[Android]Android开发艺术探索第13章笔记
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方法中设置一下即可
//在这里为应用设置异常处理程序,然后我们的程序才能捕获未处理的异常
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this);
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,当待安装的应用的方法数比较多的时候,尽管它还没有达到最大方法数,但是它的存储空间仍然有可能超过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 {
...
defaultConfig {
...
multiDexEnabled true // [添加的配置] enable multidex support
}
...
}
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和使用apktool对apk进行二次打包,比较简单,略过不总结。
[Android]Android开发艺术探索第13章笔记的更多相关文章
- [Android]Android开发艺术探索第1章笔记
1.1 Activity 的生命周期全面分析 1.1.1 典型情况下的生命周期分析 onPause: 正在停止,正常情况下紧接着 onStop 就会被调用,然后新的 Activity 执行 onRes ...
- Android开发艺术探索第五章——理解RemoteViews
Android开发艺术探索第五章--理解RemoteViews 这门课的重心在于RemoteViews,RemoteViews可以理解为一种远程的View,其实他和远程的Service是一样的,Rem ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程
第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...
- Android开发艺术探索——第二章:IPC机制(中)
Android开发艺术探索--第二章:IPC机制(中) 好的,我们继续来了解IPC机制,在上篇我们可能就是把理论的知识写完了,然后现在基本上是可以实战了. 一.Android中的IPC方式 本节我们开 ...
- Android开发艺术探索——第二章:IPC机制(上)
Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Android开发艺术探索——新的征程,程序人生路漫漫!
Android开发艺术探索--新的征程,程序人生路漫漫! 偶尔写点东西分享,但是我还是比较喜欢写笔记,看书,群英传看完了,是学到了点东西,开始看这本更加深入Android的书籍了,不知道适不适合自己, ...
- 《Android开发艺术探索》图书勘误
第一章 在13页提到"系统仅仅在Activity异常终止的时候才会调用onSaveInstanceState与onRestoreInstanceState来储存和恢复数据.其它情况不会触发这 ...
随机推荐
- 深入理解JVM - 垃圾收集器与内存分配策略 - 第三章
引用计数算法——判断对象是否存活的算法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象 ...
- android使用mina需要注意的问题
1.第三方jar包的使用 如果在Java Build Path中使用Add External JARs这种方式,运行时会有找不到类的错误(我的上面有,如果你没出现,恭喜你),上网查了几种方 ...
- LightOJ 1132 Summing up Powers:矩阵快速幂 + 二项式定理
题目链接:http://lightoj.com/volume_showproblem.php?problem=1132 题意: 给定n.k,求(1K + 2K + 3K + ... + NK) % 2 ...
- the art of seo(chapter ten)
Mobile, Local, and Vertical SEO ***The Mobile Landscape***Mobile site speed:• Google Page Speed Insi ...
- 疑难杂症:SQLServerAgent 当前未运行,因此无法将此操作通知它。
日志信息:SQLServerAgent 当前未运行,因此无法将此操作通知它. (Microsoft SQL Server,错误: 22022) 确认问题之后,远程到服务器.按照以下步骤 1.打开计算 ...
- python function with variadic arguments or keywords(dict) 可变参数与关键字参数
*args 表示任意个普通参数,调用的时候自动组装为一个tuple **kwags 表示任意个字典类型参数, 调用的时候自动组装成一个dict args和kwags是两个约定俗成的用法. 变长参数可以 ...
- ACM学习历程—HDU 1276 士兵队列训练问题(队列)
Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠 拢,再从头开始进行一至三报数,凡 ...
- 洛谷【P3437】[POI2006]TET-Tetris 3D
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 浅谈标记永久化:https://www.cnblogs.com/AKMer/p/1013 ...
- tyvj1061移动服务——DP
题目:http://www.joyoi.cn/problem/tyvj-1061 DP记录状态为当前任务时不在此任务位置上的两个人的位置(因为一定有一个人在此任务位置上): 不妨设初始位置p[0]=3 ...
- 蓝桥杯Log大侠(线段树单点区间更新)
标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...