Android探索之旅 | StrictMode严苛模式

2023-10-20 08:59

本文主要是介绍Android探索之旅 | StrictMode严苛模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

-- 作者 谢恩铭 转载请注明出处

##StrictMode简介


StrictMode (android.os.StrictMode) 是一个自Android 2.3版(API 9。Gingerbread,姜饼)引入的类。

StrictMode是Strict和Mode的合并,在英语中,strict表示“严格的”,mode表示“模式”,因此,StrictMode就是“严格的模式”,或叫“严苛模式”。

既然是严苛的,那么肯定是对什么东西有限制。因为严格的老师肯定不会对坏学生纵容的,对吧,所以可以想见StrictMode是用来监测Android中的什么东西。

严苛的老师

是的,聪明如你果然猜对了。StrictMode就是用来指定一系列策略(policy),对相应规则(rule)进行检查并且做出反应。

这些策略大致包括Android的编码规范,例如监控在主线程(UI线程)中的操作,等等。

StrictMode有不同的策略,每种策略又用不同的规则(rule),每种规则又对应不同的方法,一旦规则被违反,这些对应的方法就会被用来做出反应。

注意 :

  • 在Debug模式启用StrictMode,别在Release模式启用。用户的小心脏是很脆弱的,假如一点点违规就导致应用崩溃,或者弹窗,那用户会把你的应用删除了。
  • 特别地, 调用JNI实现的磁盘读写操作和网络操作不会激活StrictMode。

##策略类型


目前,有两种类型的策略:

  • Thread Policy : 线程策略应用到特定的线程。
  • VM Policy : VM是Virtual Machine的缩写,表示“虚拟机”,不要搞错以为是Virtual Memory(虚拟内存)。应用于虚拟机进程中的所有线程。

ThreadPolicy.Builder中的一些方法:

  • detectAll() : 侦测一切潜在违规
  • detectCustomSlowCalls() : 侦测自定义的耗时操作
  • detectDiskReads() : 侦测磁盘读
  • detectDiskWrites() : 侦测磁盘写
  • detectNetwork() : 侦测网络操作
  • permitAll() : 禁用所有侦测
  • permitDiskReads() : 允许磁盘读

VmPolicy.Builder中的一些方法 :

  • detectAll() : 侦测一切潜在违规
  • detectActivityLeaks() : 侦测Activity(活动)泄露
  • detectLeakedClosableObjects() : 当显式中止方法调用之后,假如可被Closeable类或其他的对象没有被关闭。

##处罚


Penalty是英语“处罚”的意思,所以凡是以penalty开头的方法都表示违规时要做出什么反应。

对于每个策略,我们可以指定多个处罚形式,而处罚也是从最不严重的到最严重(从打印日志到直接crash(崩溃))依次执行。

暂时还没有机制能使监测到的违规与特定的处罚对应。

  • penaltyDeath() : 违规时,直接使应用崩溃。
  • penaltyDialog() : 违规时,向开发者显示一个恼人的Dialog对话框。
  • penaltyLog() : 违规时,将违规信息写入系统日志。

##使用


StrictMode使用起来非常简单。

###设置策略

你可以在你的Application(应用)或者应用中的Activity的onCreate()方法中设置启用StrictMode的策略。不过为了更全面的监测,最好就放在Application的onCreate()方法中,一劳永逸。

设置StrictMode可以通过setVmPolicy(StrictMode.VmPolicy)或setThreadPolicy(StrictMode.ThreadPolicy)。

setVmPolicy(StrictMode.VmPolicy)或setThreadPolicy(StrictMode.ThreadPolicy)方法的参数是用VmPolicy.Builder或ThreadPolicy.Builder来构建的。

举例:

@Override
public void onCreate() {super.onCreate();// 分别为MainThread和VM设置Strict Mode if (BuildConfig.DEBUG) {StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().detectResourceMismatches().detectCustomSlowCalls().penaltyDeath().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().detectLeakedRegistrationObjects().detectActivityLeaks().penaltyDeath().build());}
}

###扩充StrictMode


1.用getThreadPolicy() 或getVmPolicy()获得当前策略。 2.用setThreadPolicy() or setVmPolicy()来扩充它。

举例:

StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(oldThreadPolicy).permitDiskWrites()  // 在原有策略的规则基础上,不监测读写磁盘.build());StrictMode.VmPolicy oldVmPolicy = StrictMode.getVmPolicy();
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder(oldVmPolicy).detectFileUriExposure()   // 在原有策略的规则基础上,监测文件URI暴露.build());

###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)

可以看到,在Logcat中总会有StrictMode开头的Log。因此,我们可以这样查找所有StrictMode的日志:

adb logcat | grep StrictMode

##测试实例


###写入外部存储

public void writeToExternalStorage() {File externalStorage = Environment.getExternalStorageDirectory();File destFile = new File(externalStorage, "dest.txt");try {OutputStream output = new FileOutputStream(destFile, true);output.write("coderunity.com".getBytes());output.flush();output.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
}

###Activity泄露


下面的代码,如果我们进入、退出多次LeakyActivity, 则会触发 StrictMode.ThreadPolicy.Builder().detectActivityLeaks() :

public class MyApplication extends Application {public static final boolean IS_DEBUG = true;public static ArrayList<Activity> sLeakyActivities = new ArrayList<Activity>();
}public class LeakyActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);MyApplication.sLeakyActivities.add(this);}
}

##在设置中启用StrictMode


我们也可以在Android设备的设置(Settings)中启用StrictMode:

Settings(设置) -> Developer options(开发者选项),然后开启它。开启之后,一旦应用在主线程中执行耗时操作,屏幕就会闪烁。

在开发者选项中开启StrictMode


人世间, 万千情感皆有温度, 千万代码似有性格。 这里有原创教程,IT丛林...... 和你一起探索程序人生。 我是谢恩铭,在巴黎奋斗的嵌入式软件工程师。 个人简介 热爱生活,喜欢游泳,略懂烹饪。 人生格言:“向着标杆直跑”

转载于:https://my.oschina.net/cxylm/blog/873072

这篇关于Android探索之旅 | StrictMode严苛模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/246082

相关文章

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

SQL Server身份验证模式步骤和示例代码

《SQLServer身份验证模式步骤和示例代码》SQLServer是一个广泛使用的关系数据库管理系统,通常使用两种身份验证模式:Windows身份验证和SQLServer身份验证,本文将详细介绍身份... 目录身份验证方式的概念更改身份验证方式的步骤方法一:使用SQL Server Management S

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Redis高可用-主从复制、哨兵模式与集群模式详解

《Redis高可用-主从复制、哨兵模式与集群模式详解》:本文主要介绍Redis高可用-主从复制、哨兵模式与集群模式的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Redis高可用-主从复制、哨兵模式与集群模式概要一、主从复制(Master-Slave Repli

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整