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

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序