StrictMode使用

StrictMode使用【IT168技术】最新的Android平台中(Android2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode)。这个类可以用来帮助开发者改进他们编写的应用,并且提供了各种的策略,这些策略能随时检查和报告开发者开发应用中存在的问题,比如可以监视那些本不应该在主线程中完成的工作或者其他的一些不规范和不好的代码。  StrictMode有多种不

大家好,又见面了,我是你们的朋友全栈君。

【IT168技术】最新的Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode)。这个类可以用来帮助开发者改进他们编写的应用,并且提供了各种的策略,这些策略能随时检查和报告开发者开发应用中存在的问题,比如可以监视那些本不应该在主线程中完成的工作或者其他的一些不规范和不好的代码。

  StrictMode有多种不同的策略,每一种策略又有不同的规则,当开发者违背某个规则时,每个策略都有不同的方法去显示提醒用户。在本文中,将举例子说明如何使用在Android 中使用 StrictMode。

  StrictMode的策略和规则

  目前,有两大类的策略可供使用,一类是关于常用的监控方面的,另外一类是关于VM虚拟机等方面的策略。常用的监控方面的策略有如下这些:

  Disk Reads 磁盘读

  Disk Writes 磁盘写

  Network access 网络访问

  Custom Slow Code 自定义的运行速度慢的代码分析

  前面三种的意思读者应该很清楚,就是正如它们的名字所示,分别对磁盘的读和写,网络访问进行监控。而第四种的自定义慢代码分析,是仅当访问调用类的时后才触发的,可以通过这种方法去监视运行缓慢的代码。当在主线程中调用时,这些验证规则就会起作用去检查你的代码。比如,当你的应用在下载或者解析大量的数据时,你可以触发自定义运行速度慢代码的查询分析,作用很大。StrictMode可以用于捕捉发生在应用程序主线程中耗时的磁盘、网络访问或函数调用,可以帮助开发者使其改进程序,使主线程处理UI和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞的发生。

  而VM方面的策略重点关注如下几类:

  内存泄露的Activity对象

  内存泄露的SQLite对象

  内存泄露的释放的对象

  其中,内存泄露的Activity对象和内存泄露的SQLite对象都比较好理解,而所谓对关闭对象的检查,主要是去监那些本该释放的对象,比如应该调用close()方法的对象。

  当开发者违反某类规则时,每种策略都会有不同的方法令开发者知道当时的情况。相关的违反情况可以记录在LogCat中或者存储在DropBox中(android.os.DropBox)服务中。而常用监控类的策略还会在当违规情况发生时显示相关的对话框和当时的上下文环境,所有的这些都为了能让开发者尽快地了解程序的瑕疵,以提交程序的质量。下面分步讲解如何使用stritctmode。


  第一步 启用strictmode

  为了能在应用中启用和配置StrictMode,开发者最好尽可能在应用程序的生命周期的早段使用,方法是调用StrictMode的方法setThreadPolicy。当使用常用监控类的时候,一个最好的调用时机,是在应用中入口和activities被调用前进行。比如在一个应用程序中,可以把代码放在启动Activity类的onCreate()方法中,下面是一个代码示例,启用了当前情况下的所有策略及规则,当程序中出现违背常用的规则时,将会显示相关的提示信息窗口:

StrictMode.setThreadPolicy(new
 StrictMode.ThreadPolicy.Builder()
.detectAll() 
.penaltyLog() 
.penaltyDialog() 


打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
.build()); 
StrictMode.setVmPolicy(
new
 StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog() 
.build());

当然,以上代码只应在未发布上线的测试版本的应用中运行以方便监视相关的运行情况,当在生产版本上时不应该启用strictmode。因此,最佳的代码实践应该为如下的样子:

public
 void onCreate() {

if
 (DEVELOPER_MODE) {

StrictMode.setThreadPolicy(
new
 StrictMode.ThreadPolicy.Builder()
.detectDiskReads() 
.detectDiskWrites() 
.detectNetwork() 
.penaltyLog() 
.build()); 

super.onCreate(); 
}

 

 第二步 运行strictmode

  当应用启用了strictmode模式时,其实跟普通的应用没什么两样,在测试和运行时,跟平时运行普通应用程序一样就可以了。当启用了Strictmode模式时,会监视所有的程序运行情况,当发现出现重大问题或违背策略规则时,会提示用户。下面是当运行启用了strictmode模式的应用时,当发现违背规则时,显示给用户的信息,细心观察下跟普通的出错信息有什么不同吧。

09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): StrictMode policy violation; ~duration
=319
 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy
=31
 violation
=1

09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1041
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:219
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:83
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1829
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1780
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at com.mamlambo.tutorial.tutlist.data.TutListProvider.update(TutListProvider.java:188
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.content.ContentProvider$Transport.update(ContentProvider.java:233
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.content.ContentResolver.update(ContentResolver.java:847
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at com.mamlambo.tutorial.tutlist.data.TutListProvider.markItemRead(TutListProvider.java:229
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at com.mamlambo.tutorial.tutlist.TutListFragment.onListItemClick(TutListFragment.java:99
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.support.v4.app.ListFragment$2
.onItemClick(ListFragment.java:53
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.widget.AdapterView.performItemClick(AdapterView.java:282
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.widget.AbsListView.performItemClick(AbsListView.java:1037
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2449
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.widget.AbsListView$1
.run(AbsListView.java:3073
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.os.Handler.handleCallback(Handler.java:587
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.os.Handler.dispatchMessage(Handler.java:92
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.os.Looper.loop(Looper.java:132
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at android.app.ActivityThread.main(ActivityThread.java:4123
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at java.lang.reflect.Method.invokeNative(Native Method)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at java.lang.reflect.Method.invoke(Method.java:491
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599
)
09
04
16
:15
:34.592
: DEBUG
/
StrictMode(15883
): at dalvik.system.NativeStart.main(Native Method

 并且会出现如下的提示窗口,提示用户:

StrictMode使用

  忽略某些规则

  应该说大部分由StrictMode产生的规则警示都应去遵守,但有时也不是所有产生的信息都表明你的程序有错误。比如,在应用程序的主线程中去快速读写磁盘其实不会对应用的性能产生太大的影响,又或者你在调试程序阶段有一些调试的代码违反了设定的规则,这些都可以忽略掉这些规则。

  忽略规则有两种方法,一种是单纯在代码中把Strictmode的代码注释掉,另外一种比较好的方法是,在需要忽略的时候和地方,增加相应的代码去让系统停止使用这些规则去检查,等开发者认为有必要检查时,再重新应用这些规则,比如:

  StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();

  StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)

  .permitDiskWrites()

  .build());

  doCorrectStuffThatWritesToDisk();

  StrictMode.setThreadPolicy(old);

  这里首先用old来保存了当前的策略规则,然后doCorrectStuffThatWritesToDisk();

  这里,执行了一些向磁盘快速读写的操作,最后又重新启用了这些规则。

  小结

  StrictMode是一个十分有用的类,它可以很方便地应用于检查Android应用程序的性能和存在的问题。当开启这个模式后,开发者能很好地检查应用中存在的潜在问题,更多的请参考Android文档中的相关API说明。

转文

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132759.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • XOOPS模块开发快速入门中文翻译(二)

    XOOPS模块开发快速入门中文翻译(二)由于这两天一直研究XOOPS的模块,所以找到了这篇很好的模块开发快速入门。看了以后,就兴致勃勃的来开发模块了,可是开发的过程中遇到一些问题。应该是我看的太快了,要学而时习之啊。因此翻译在这里。=

    2022年7月2日
    26
  • linux(4)Linux 文件内容查看「建议收藏」

    linux(4)Linux 文件内容查看「建议收藏」查看文件内容总览cat由第一行开始显示文件内容tac从最后一行开始显示,可以看出tac是cat的倒着写!nl显示的时候,顺道输出行号!more一页一页的显示文件内容less

    2022年7月28日
    7
  • Windows Task Scheduler创建一个程序自动运行任务

    Windows Task Scheduler创建一个程序自动运行任务WindowsTaskS 使用户可以在此计算机上配置和计划自动任务 同时托管多个 Windows 系统关键任务

    2025年6月18日
    3
  • 憨批的语义分割重制版6——Pytorch 搭建自己的Unet语义分割平台「建议收藏」

    憨批的语义分割重制版6——Pytorch 搭建自己的Unet语义分割平台「建议收藏」憨批的语义分割13——Pytorch搭建自己的Unet语义分割平台注意事项学习前言什么是Unet模型代码下载Unet实现思路一、预测部分1、主干网络介绍2、加强特征提取结构3、利用特征获得预测结果二、训练部分1、训练文件详解2、LOSS解析训练自己的Unet模型注意事项这是重新构建了的Unet语义分割网络,主要是文件框架上的构建,还有代码的实现,和之前的语义分割网络相比,更加完整也更清晰一些。建议还是学习这个版本的Unet。学习前言还是快乐的pytorch人。什么是Unet模型Unet是一个

    2022年6月15日
    24
  • 电压转电流电路

    电压转电流电路图1 电压转电流原理图   如图 1是输入输出无偏置型电压转电流信号调理的典型电路。其中运放A、电阻R13、三极管Q10构成压控电流源电路;电阻R9、R11、运放B、三极管Q8、Q9构成电流放大电路。   当电压信号加在运放A同向输入时,由运放特性:虚短、虚断可知反向输入端电压跟随同向输入端电压信号,此时在电阻R13支路上产生电流流过三极管Q10,三极管Q10基极受运放A输出端

    2022年6月2日
    38
  • Mybatis 注解开发 + 动态SQL

    Mybatis 注解开发 + 动态SQLHello 大家好我是橙子同学 今天分享注解 Mybatis 注解开发 动态 sql 目录每文一铺垫 今天有小插曲哦 注解开发添加 Insert 删除 Delete 查询 Select 修改 Update 实现结果集封装 Result 实现一对一结果集封装 one 实现多对多结果集封装 Many 动态 SQL 标签 set if 标签 if set

    2025年6月27日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号