App优化 StrictMode 严格模式
StrictMode简介
StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例。除了主线程,我们还可以在Handler,AsyncTask,AsyncQueryHandler,IntentService等API中使用StrictMode。

检查策略
StrictMode的线程策略主要用于检测磁盘IO和网络访问,而虚拟机策略主要用于检测内存泄漏现象。Android已经在磁盘IO访问和网络访问的代码中加入了StrictMode。当监视的线程发生策略的违例时,就可以获得警告,例如写入LogCat,显示一个对话框,闪下屏幕,写入DropBox日志文件,或让应用崩溃。最通常的做法是写入LogCat或让应用崩溃。下面的代码展示了如何使用StrictMode的检查策略:
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() //线程策略
.detectDiskReads() //detect [dɪˈtɛkt] vt.查明,发现; 洞察; 侦察,侦查;
.detectDiskWrites()
.detectNetwork()
// or .detectAll() for all detectable problems
.penaltyDialog() //penalty [ˈpɛnəlti] n.刑罚; 惩罚; 害处
.penaltyLog()
.penaltyDropBox() //DropBox下拉框
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() //虚拟机策略
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() //线程策略
.detectDiskReads() //detect [dɪˈtɛkt] vt.查明,发现; 洞察; 侦察,侦查;
.detectDiskWrites()
.detectNetwork()
// or .detectAll() for all detectable problems
.penaltyDialog() //penalty [ˈpɛnəlti] n.刑罚; 惩罚; 害处
.penaltyLog()
.penaltyDropBox() //DropBox下拉框
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() //虚拟机策略
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
使用方法
如果不指定检测函数,也可以用detectAll()来替代。penaltyLog()表示将警告输出到LogCat,你也可以使用其他或增加新的惩罚(penalty)函数,例如使用penaltyDeath()的话,一旦StrictMode消息被写到LogCat后应用就会崩溃。具体支持的监视方法见:StrictMode.ThreadPolicy.Builder 与 StrictMode.VmPolicy.Builder。
在正式版本中,我们并不希望使用StrictMode来让用户的应用因为一个警告而崩溃,所以在应用正式发布时,需要移出这些监视。你可以通过删除代码来实现,不过这里提供一个更好的方式来解决这个问题,即使用AndroidMainifest文件中的debuggable属性来实现,代码如下所示:
android:debuggable="true"
android:debuggable="true"
PS:可能在gradle中这么配置也行
android {
buildTypes {
debug {
debuggable true
}
}
}
android {
buildTypes {
debug {
debuggable true
}
}
}
在代码中,使用方法如下所示:
// Return if this application is not in debug mode
if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// Do StrictMode setup here
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
// Return if this application is not in debug mode
if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// Do StrictMode setup here
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
实例
我们在测试代码的主线程中去访问网络,这样就一定会触发StrictMode的线程监测,代码如下所示:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyDialog()
.penaltyLog()
.penaltyDropBox()
.build());
super.onCreate(savedInstanceState);
TextView mTextView = new TextView(this);
setContentView(mTextView);
InputStream inputStream = null;
try {
HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com"));
HttpEntity httpEntity = httpResponse.getEntity();
if (httpResponse.getStatusLine().getStatusCode() == 200) {
inputStream = httpEntity.getContent();
mTextView.setText(new BufferedReader(new InputStreamReader(inputStream)).readLine());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyDialog()
.penaltyLog()
.penaltyDropBox()
.build());
super.onCreate(savedInstanceState);
TextView mTextView = new TextView(this);
setContentView(mTextView);
InputStream inputStream = null;
try {
HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com"));
HttpEntity httpEntity = httpResponse.getEntity();
if (httpResponse.getStatusLine().getStatusCode() == 200) {
inputStream = httpEntity.getContent();
mTextView.setText(new BufferedReader(new InputStreamReader(inputStream)).readLine());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行代码,并将Log信息保存到本地,在Log中,我们可以搜索D/StrictMode关键字,如下所示:
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2
at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1157)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:182)
at libcore.io.IoBridge.open(IoBridge.java:480)
at java.io.FileInputStream.<init>(FileInputStream.java:76)
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at android.content.res.HwResources.readDefaultConfig(HwResources.java:1172)
at android.content.res.HwResources.loadDrawable(HwResources.java:574)
at android.content.res.Resources.getDrawable(Resources.java:809)
at android.content.Context.getDrawable(Context.java:403)
at com.android.internal.widget.ToolbarWidgetWrapper.setIcon(ToolbarWidgetWrapper.java:321)
at com.android.internal.widget.ActionBarOverlayLayout.setIcon(ActionBarOverlayLayout.java:741)
at com.android.internal.policy.impl.PhoneWindow.setDefaultIcon(PhoneWindow.java:1661)
at android.app.Activity.initWindowDecorActionBar(Activity.java:2174)
at android.app.Activity.setContentView(Activity.java:2189)
at com.imooc.strictmodetest.MainActivity.onCreate(MainActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6102)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$1200(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2
at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1157)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:182)
at libcore.io.IoBridge.open(IoBridge.java:480)
at java.io.FileInputStream.<init>(FileInputStream.java:76)
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at android.content.res.HwResources.readDefaultConfig(HwResources.java:1172)
at android.content.res.HwResources.loadDrawable(HwResources.java:574)
at android.content.res.Resources.getDrawable(Resources.java:809)
at android.content.Context.getDrawable(Context.java:403)
at com.android.internal.widget.ToolbarWidgetWrapper.setIcon(ToolbarWidgetWrapper.java:321)
at com.android.internal.widget.ActionBarOverlayLayout.setIcon(ActionBarOverlayLayout.java:741)
at com.android.internal.policy.impl.PhoneWindow.setDefaultIcon(PhoneWindow.java:1661)
at android.app.Activity.initWindowDecorActionBar(Activity.java:2174)
at android.app.Activity.setContentView(Activity.java:2189)
at com.imooc.strictmodetest.MainActivity.onCreate(MainActivity.java:36)
at android.app.Activity.performCreate(Activity.java:6102)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$1200(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
主要看第一行
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2
这行Log中可以显示出StrictMode提示的原因,通过这里的TraceLog我们就可以来找到优化的方法。
除了在Logcat中查看StrictMode的日志信息,如果你使用了penaltyDropbox()方法,那么你还可以通过如下所示的命令来调用DropBoxManager观察StrictMode日志:
adb shell dumpsys dropbox data_app_strictmode --print
adb shell dumpsys dropbox data_app_strictmode --print
同时,如果使用了penaltyDialog()方法,在应用中还会弹出如下所示的提示框:

暂停监测
StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
.permitDiskWrites()
.build());
//doSomethingWriteToDisk();
StrictMode.setThreadPolicy(old);
x
StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
.permitDiskWrites()
.build());
//doSomethingWriteToDisk();
StrictMode.setThreadPolicy(old);
2017-10-20
App优化 StrictMode 严格模式的更多相关文章
- 4.Android App 优化之消除卡顿
转载:http://gold.xitu.io/post/582583328ac247004f3ab124 1, 感知卡顿 用户对卡顿的感知, 主要来源于界面的刷新. 而界面的性能主要是依赖于设备的UI ...
- 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化
联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...
- Android App优化之ANR详解
引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...
- 0428数字口袋精灵app优化
"数字口袋精灵app"优化 目录: 一.项目github总仓库推送 二.开发成员 三.分工与合作 四.各模块成果 五.团队成员贡献分 内容: 一.项目github总仓库: http ...
- [实践] Android5.1.1源码 - 让某个APP以解释执行模式运行
[实践] Android5.1.1源码 - 让某个APP以解释执行模式运行 作者:寻禹@阿里聚安全 前言 本文的实践修改了Android5.1.1的源码. 本文只简单的讲了一下原理.在“实践”一节 ...
- App开发三种模式
APP开发三种模式 现在App开发的模式包含以下三种: Native App 原生开发AppWeb App 网页AppHybrid App 混合原生和Web技术开发的App 详细介绍: http:// ...
- 【高德地图API】那些年我们一起开发的APP—即LBS应用模式分享
原文:[高德地图API]那些年我们一起开发的APP—即LBS应用模式分享 摘要:利用地图API都能做些什么应用呢?应用商店里所有的分类,都可以结合上LBS来丰富应用.除了传统的生活服务应用,还有新潮的 ...
- Android App优化建议(转载)
假如要Google Play上做一个最失败的案例,那最好的秘诀就是界面奇慢无比.耗电.耗内存.接下来就会得到用户的消极评论,最后名声也就臭了.即使你的应用设计精良.创意无限也没用. 耗电或者内存占用等 ...
- App优化 Systrace
简介 trace [tres] vt.跟踪,追踪; 追溯,探索; 探索; 查找; n.痕迹; 痕迹,踪迹; 微量,极少量; 1 1 1 trace [tres] vt.跟踪,追踪; 追溯,探索; ...
随机推荐
- 使用 Python 可以做什么?
翻译自 <Python学习手册(第5版)> Systems Programming Python 对操作系统服务的内置接口使其非常适合编写可移植.可维护的系统管理工具和实用程序 utili ...
- My blog in AI ---神经网络,神经元(neural network,nervecell)
尽管我们有很多经验丰富的软件开发人员,但是利用hard code的方法,要解决一些问题,我们的程序员还是优点捉襟见肘,这些问题包括,识别手写数字照片上的数字:分辨一张彩色照片上是否有一只猫咪:准确理解 ...
- 浅谈 Java 中的枚举
枚举也就是一一列举,常用来表示那些可以明确范围的集合,比方说性别,季节,星期,月份等. 在 JDK 1.5 才出现枚举类,在没有出现枚举类之前,我们要表示几个确定的值通常会使用常量来表示,形如 pub ...
- [leetcode tree]104. Maximum Depth of Binary Tree
求树的最大深度 class Solution(object): def maxDepth(self, root): if not root: return 0 left = self.maxDepth ...
- Replication Controller
RC保证在同一时间能够运行指定数量的Pod副本,保证Pod总是可用.如果实际Pod数量比指定的多就结束掉多余的,如果实际数量比指定的少就启动缺少的. 当Pod失败.被删除或被终结时,RC会自动创建新的 ...
- 希尔排序之Java实现
希尔排序之Java实现 一.方法一 package cn.com.zfc.lesson21.sort; /** * * @title ShellSort * @describe 希尔排序 1959 年 ...
- BZOJ1878: [SDOI2009]HH的项链[树状数组+离线 | 主席树]
题意: 询问区间不同种类颜色数 [2016-11-15] 离线好厉害 对于每一个区间询问,一个数只考虑一次,那么考虑他最后出现的一次 将询问按r排序 从1到n扫描,用树状数组维护一个位置应不应该考虑( ...
- hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树
题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值 将已连接的两点权值置为0,这样一定能加入最小生成树里 最后的结果加上这两点的距离即为所求 #include<cstdio& ...
- poj 1273 Drainage Ditches 网络流最大流基础
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 59176 Accepted: 2272 ...
- [Visual Studio] 安装清单
VS安装位置要求路径必须是英文,且位于Program Files (x86)文件夹下. 下载工具vs_Professional.exe:https://pan.baidu.com/s/1jHRjiia ...