StrictMode简介

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

示例代码  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();
}
21
21
 
1
public void onCreate() {  
2
     if (DEVELOPER_MODE) {  
3
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()  //线程策略
4
                 .detectDiskReads()  //detect [dɪˈtɛkt] vt.查明,发现; 洞察; 侦察,侦查;
5
                 .detectDiskWrites()  
6
                 .detectNetwork()   
7
                 // or .detectAll() for all detectable problems 
8
                 .penaltyDialog()  //penalty [ˈpɛnəlti] n.刑罚; 惩罚; 害处
9
                 .penaltyLog()  
10
                 .penaltyDropBox()  //DropBox下拉框
11
                 .build());  
12
         
13
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  //虚拟机策略
14
                 .detectLeakedSqlLiteObjects()  
15
                 .detectLeakedClosableObjects()  
16
                 .penaltyLog()  
17
                 .penaltyDeath()  
18
                 .build());  
19
     }  
20
     super.onCreate();  
21
 }  

使用方法

如果不指定检测函数,也可以用detectAll()来替代。penaltyLog()表示将警告输出到LogCat,你也可以使用其他或增加新的惩罚(penalty)函数,例如使用penaltyDeath()的话,一旦StrictMode消息被写到LogCat后应用就会崩溃。具体支持的监视方法见:StrictMode.ThreadPolicy.Builder 与 StrictMode.VmPolicy.Builder

在正式版本中,我们并不希望使用StrictMode来让用户的应用因为一个警告而崩溃,所以在应用正式发布时,需要移出这些监视。你可以通过删除代码来实现,不过这里提供一个更好的方式来解决这个问题,即使用AndroidMainifest文件中的debuggable属性来实现,代码如下所示:

android:debuggable="true"  
1
1
 
1
android:debuggable="true"  

PS:可能在gradle中这么配置也行

android {
buildTypes {
debug {
debuggable true
}
}
}
7
7
 
1
android {    
2
    buildTypes {
3
        debug {
4
            debuggable true
5
        }
6
    }
7
}

在代码中,使用方法如下所示:

// 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());
}
9
9
 
1
// Return if this application is not in debug mode
2
if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {   
3
    // Do StrictMode setup here   
4
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()   
5
        .detectLeakedSqlLiteObjects()   
6
        .penaltyLog()   
7
        .penaltyDeath()   
8
        .build());   
9
}  

实例

我们在测试代码的主线程中去访问网络,这样就一定会触发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();
}
}
}
}
35
35
 
1
public class MainActivity extends Activity {
2
    @Override
3
    protected void onCreate(Bundle savedInstanceState) {
4
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
5
                .detectDiskReads()
6
                .detectDiskWrites()
7
                .detectNetwork()
8
                .penaltyDialog()
9
                .penaltyLog()
10
                .penaltyDropBox()
11
                .build());
12
        super.onCreate(savedInstanceState);
13
        
14
        TextView mTextView = new TextView(this);
15
        setContentView(mTextView);
16
        
17
        InputStream inputStream = null;
18
        try {
19
            HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com"));
20
            HttpEntity httpEntity = httpResponse.getEntity();
21
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
22
                inputStream = httpEntity.getContent();
23
                mTextView.setText(new BufferedReader(new InputStreamReader(inputStream)).readLine());
24
            }
25
        } catch (Exception e) {
26
            e.printStackTrace();
27
        } finally {
28
            try {
29
                if (inputStream != null) inputStream.close();
30
            } catch (IOException e) {
31
                e.printStackTrace();
32
            }
33
        }
34
    }
35
}

运行代码,并将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)
29
29
 
1
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2
2
      at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1157)
3
      at libcore.io.BlockGuardOs.open(BlockGuardOs.java:182)
4
      at libcore.io.IoBridge.open(IoBridge.java:480)
5
      at java.io.FileInputStream.<init>(FileInputStream.java:76)
6
      at java.io.FileInputStream.<init>(FileInputStream.java:103)
7
      at android.content.res.HwResources.readDefaultConfig(HwResources.java:1172)
8
      at android.content.res.HwResources.loadDrawable(HwResources.java:574)
9
      at android.content.res.Resources.getDrawable(Resources.java:809)
10
      at android.content.Context.getDrawable(Context.java:403)
11
      at com.android.internal.widget.ToolbarWidgetWrapper.setIcon(ToolbarWidgetWrapper.java:321)
12
      at com.android.internal.widget.ActionBarOverlayLayout.setIcon(ActionBarOverlayLayout.java:741)
13
      at com.android.internal.policy.impl.PhoneWindow.setDefaultIcon(PhoneWindow.java:1661)
14
      at android.app.Activity.initWindowDecorActionBar(Activity.java:2174)
15
      at android.app.Activity.setContentView(Activity.java:2189)
16
      at com.imooc.strictmodetest.MainActivity.onCreate(MainActivity.java:36)
17
      at android.app.Activity.performCreate(Activity.java:6102)
18
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
19
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
20
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
21
      at android.app.ActivityThread.access$1200(ActivityThread.java:165)
22
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
23
      at android.os.Handler.dispatchMessage(Handler.java:102)
24
      at android.os.Looper.loop(Looper.java:135)
25
      at android.app.ActivityThread.main(ActivityThread.java:5593)
26
      at java.lang.reflect.Method.invoke(Native Method)
27
      at java.lang.reflect.Method.invoke(Method.java:372)
28
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967)
29
      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
1
1
 
1
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
1
1
 
1
adb shell dumpsys dropbox data_app_strictmode --print

同时,如果使用了penaltyDialog()方法,在应用中还会弹出如下所示的提示框:


暂停监测

如果在程序运行中无法避免的会违反StrictMode中的一些定义好的策略,而我们又希望能够暂时忽略这些策略的监视,我们可以使用permitXXXXX方法来暂停这些内容的监测,在做完需要忽略的监测之后,再启用监测,代码如下所示:
StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
.permitDiskWrites()
.build());
//doSomethingWriteToDisk();
StrictMode.setThreadPolicy(old);
x
 
1
StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();  
2
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)  
3
        .permitDiskWrites()  
4
        .build());  
5
//doSomethingWriteToDisk();  
6
StrictMode.setThreadPolicy(old);  

2017-10-20

App优化 StrictMode 严格模式的更多相关文章

  1. 4.Android App 优化之消除卡顿

    转载:http://gold.xitu.io/post/582583328ac247004f3ab124 1, 感知卡顿 用户对卡顿的感知, 主要来源于界面的刷新. 而界面的性能主要是依赖于设备的UI ...

  2. 斗牛app上架应用宝、牛牛手机游戏推广、百人牛牛app应用开发、棋牌游戏上传、手游APP优化

    联系QQ:305-710439斗牛app上架应用宝.牛牛手机游戏推广.百人牛牛app应用开发.棋牌游戏上传.手游APP优化 iOS开发iPhone/iPad平台安卓手机软件开发机型覆盖范围 超过113 ...

  3. Android App优化之ANR详解

    引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...

  4. 0428数字口袋精灵app优化

    "数字口袋精灵app"优化 目录: 一.项目github总仓库推送 二.开发成员 三.分工与合作 四.各模块成果 五.团队成员贡献分 内容: 一.项目github总仓库: http ...

  5. [实践] Android5.1.1源码 - 让某个APP以解释执行模式运行

    [实践] Android5.1.1源码 - 让某个APP以解释执行模式运行   作者:寻禹@阿里聚安全 前言 本文的实践修改了Android5.1.1的源码. 本文只简单的讲了一下原理.在“实践”一节 ...

  6. App开发三种模式

    APP开发三种模式 现在App开发的模式包含以下三种: Native App 原生开发AppWeb App 网页AppHybrid App 混合原生和Web技术开发的App 详细介绍: http:// ...

  7. 【高德地图API】那些年我们一起开发的APP—即LBS应用模式分享

    原文:[高德地图API]那些年我们一起开发的APP—即LBS应用模式分享 摘要:利用地图API都能做些什么应用呢?应用商店里所有的分类,都可以结合上LBS来丰富应用.除了传统的生活服务应用,还有新潮的 ...

  8. Android App优化建议(转载)

    假如要Google Play上做一个最失败的案例,那最好的秘诀就是界面奇慢无比.耗电.耗内存.接下来就会得到用户的消极评论,最后名声也就臭了.即使你的应用设计精良.创意无限也没用. 耗电或者内存占用等 ...

  9. App优化 Systrace

    简介 trace [tres] vt.跟踪,追踪; 追溯,探索; 探索; 查找; n.痕迹; 痕迹,踪迹; 微量,极少量; 1 1   1 trace [tres] vt.跟踪,追踪; 追溯,探索; ...

随机推荐

  1. 【知了堂学习笔记】java 编写几种常见排序算法2

    排序的分类: 1.直接选择排序 它的基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,....,第i次从R[i-1]~ ...

  2. 掩码计算工具netmask

    掩码计算工具netmask   在网络扫描和防火墙配置中,经常需要计算IP地址范围和对应的掩码.为了简化这个过程,Kali Linux预置了一个掩码计算工具netmask.该工具不仅可以根据IP地址范 ...

  3. 求N!末尾所得数字0的个数

    题目:给定一个整数N ,那么N 的阶乘N !末尾有多少个0呢? 例如:N = 10,N! = 3628800,所以N!末尾就有2个零. 分析:如果直接先算出N!阶乘,很容易导致内存溢出.显然,直接算出 ...

  4. centOS7下SVN的安装和使用

    1. 安装 CentOS通过yum安装subversion. # yum install subversion  subversion安装在/bin目录: # which svnserve #查看目录 ...

  5. 给HTML初学者的三十条最佳实践

    Nettuts +运营最困难的方面是为很多技能水平不同的用户提供服务.如果我们发布太多高级教程,我的新手用户将无法从中受益.相反也是如此.我们尽我们最大的努力,但如果你觉得你被忽略了请联系我们.这个网 ...

  6. Problem F: 铺地砖

    Description 元旦过去了,新年大酬宾活动也已经告一段落了.陈盖历望着堆在仓库的瓷砖,很无聊的他把这些瓷砖裁成很多1X1 1X2 1X3的小瓷砖,然后他把这些小瓷砖排在地上画的一个1*n的长方 ...

  7. window.open如何返回值给父窗口

    父窗口代码 function showMyWindowNew() { var iTop = (window.screen.availHeight - 30 - 450) / 2; //获得窗口的水平位 ...

  8. Codeforces Round #FF (Div. 1) B. DZY Loves Modification 优先队列

    B. DZY Loves Modification 题目连接: http://www.codeforces.com/contest/446/problem/B Description As we kn ...

  9. RN生命周期

    网上看的博客,看着写的很好,想深入学RN的详细看下之后,再自己敲敲吧!有助于身体健康! 一个RN组件从它被加载,到最终被卸载会经历一个完整的生命周期.所谓生命周期,就是一个对象从开始生成到最后消亡所经 ...

  10. js面向对象编程-高级内容

    JavaScript面向对象 一.为每个对象动态添加属性或方法 功能:返回对象类型原型的引用 prototype的使用 格式:class.prototype 场景: 比如说:A写了一个类,交给B,B在 ...