其实还有LeakCanry
作为Android开发,日常的开发工作中或多或少要接触到性能问题,比如我的Android程序运行缓慢卡顿,并且常常出现ANR对话框等等问题。既然有性能问题,就需要进行性能优化。正所谓工欲善其事,必先利其器。一个好的工具,可以帮助我们发现并定位问题,进而有的放矢进行解决。本文主要介绍StrictMode 在Android 应用开发中的应用和一些问题。
什么是StrictMode
StrictMode意思为严格模式,是用来检测程序中违例情况的开发者工具。最常用的场景就是检测主线程中本地磁盘和网络读写等耗时的操作。
严在哪里
既然叫做严格模式,那么又严格在哪些地方呢?
在Android中,主线程,也就是UI线程,除了负责处理UI相关的操作外,还可以执行文件读取或者数据库读写操作(从Android 4.0 开始,网络操作禁止在主线程中执行,否则会抛出 NetworkOnMainThreadException )。使用严格模式,系统检测出主线程违例的情况会做出相应的反应,如日志打印,弹出对话框亦或者崩溃等。换言之,严格模式会将应用的违例细节暴露给开发者方便优化与改善。
具体能检测什么
严格模式主要检测两大问题,一个是线程策略,即TreadPolicy,另一个是VM策略,即VmPolicy。
ThreadPolicy
线程策略检测的内容有
- 自定义的耗时调用 使用 detectCustomSlowCalls() 开启
- 磁盘读取操作 使用 detectDiskReads() 开启
- 磁盘写入操作 使用 detectDiskWrites() 开启
- 网络操作 使用 detectNetwork() 开启
VmPolicy
虚拟机策略检测的内容有
- Activity泄露 使用 detectActivityLeaks() 开启
- 未关闭的Closable对象泄露 使用 detectLeakedClosableObjects() 开启
- 泄露的Sqlite对象 使用 detectLeakedSqlLiteObjects() 开启
- 检测实例数量 使用 setClassInstanceLimit() 开启
工作原理
其实StrictMode实现原理也比较简单,以IO操作为例,主要是通过在open,read,write,close时进行监控。 libcore.io.BlockGuardOs
文件就是监控的地方。以open为例,如下进行监控。
@Override
public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
if ((mode & O_ACCMODE) != O_RDONLY) {
BlockGuard.getThreadPolicy().onWriteToDisk();
}
return os.open(path, flags, mode);
}
其中 onReadFromDisk() 方法的实现,代码位于StrictMode.java中。
public void onReadFromDisk() {
if ((mPolicyMask & DETECT_DISK_READ) == 0) {
return;
}
if (tooManyViolationsThisLoop()) {
return;
}
BlockGuard.BlockGuardPolicyException e = new