Android开发之StrictMode

StrictMode简介

  • Android开发者官网对StrictMode的介绍
  • StrictMode类是Android 2.3(API 9)引入的一个工具类
  • 用来帮助开发者发现代码中一些不规范的问题,比如:
    • 在UI线程中进行了网络或磁盘操作,StrictMode就会通过LogCat或者对话框的方式把信息提示给开发者,因为UI线程处理这些操作会认为是不规范的做法,可能会让你的应用变得比较卡顿

如何启用StrictMode

  • 通常在Activity或者自定义的Application类的onCreate方法中启动StrictMode
// DEVELOPER_MODE代表只在调试模式下启用StrictMode
if (DEVELOPER_MODE) {
	StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
			.detectDiskReads()
			.detectDiskWrites()
			.detectNetwork()   // or .detectAll() for all detectable problems
			.penaltyLog()
			.build());
	StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
			.detectLeakedSqlLiteObjects()
			.detectLeakedClosableObjects()
			.penaltyLog()
			.penaltyDeath()
			.build());
}

StrictMode详解

  • StrictMode通过策略方式来让你自定义需要检查哪些方面的问题,主要有两种策略:
    • ThreadPolicy:线程方面的策略
    • VmPolicy:VM方面的策略

ThreadPolicy详解

  • StrictMode.ThreadPolicy.Builder主要方法如下:

    • detectNetwork():用于检查UI线程中是否有网络请求

    • detectDiskReads()和detectDiskWrites():是磁盘读写检查

    • detectCustomSlowCalls():主要用于帮助开发者发现UI线程中调用的哪些方法执行的比较慢,要和StrictMode.noteSlowCall配合使用,只有通过StrictMode.noteSlowCall标记“可能会”执行比较慢的方法,只有标记过的方法才能被检测到,日志中会记录方法的执行时间(注意:只有在主线程中执行的方法才会显示执行时间,在其他线程中执行的方法,就算是使用StrictMode.noteSlowCall标记,在日志中也不会打印执行时间)

    • penaltyDeath():当触发违规条件时,直接Crash掉当前应用程序

    • penaltyDeathOnNetwork():当触发网络违规时,Crash掉当前应用程序

    • penaltyDialog():触发违规时,显示对违规信息对话框

    • penaltyFlashScreen():会造成屏幕闪烁,不过一般的设备可能没有这个功能

    • penaltyDropBox():将违规信息记录到 dropbox 系统日志目录中(/data/system/dropbox),你可以通过如下命令进行插件

      adb shell dumpsys dropbox dataappstrictmode  --print
      
    • permitCustomSlowCalls()、permitDiskReads ()、permitDiskWrites()、permitNetwork: 如果你想关闭某一项检测,可以使用对应的permit*方法

    VMPloicy详解

    • detectActivityLeaks() 用户检查 Activity 的内存泄露情况
    • detectLeakedClosableObjects() 和 detectLeakedSqlLiteObjects(),资源没有正确关闭时回触发,detectLeakedSqlLiteObjects() 和 detectLeakedClosableObjects()的用法类似,只不过是用来检查 SQLiteCursor 或者 其他 SQLite 对象是否被正确关闭
    • detectLeakedRegistrationObjects() 用来检查 BroadcastReceiver 或者 ServiceConnection 注册类对象是否被正确释放
    • setClassInstanceLimit(),设置某个类的同时处于内存中的实例上限,可以协助检查内存泄露

利用调试模式的特点,在debug模式下设置StrictMode

ApplicationInfo appInfo = context.getApplicationInfo();  
int appFlags = appInfo.flags;  
if ((appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {  
    // Do StrictMode setup here  
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  
        .detectLeakedSqlLiteObjects()  
        .penaltyLog()  
        .penaltyDeath()  
        .build());  
} 

利用反射技术调用StrictMode,避免在2.3以下版本出现问题

try {  
    Class sMode = Class.forName("android.os.StrictMode");  
    Method enableDefaults = sMode.getMethod("enableDefaults"); 
    // enableDefault()是严苛模式(StrictMode)类的另一个函数,它检测所有违例并写入LogCat。因为这里调用的是静态形式的enableDefault(),所以用null作为参数传入。
    enableDefaults.invoke(null);  
}  
catch(Exception e) {  
    // StrictMode not supported on this device, punt  
    // 当严苛模式(StrictMode)不存在,将捕捉到ClassNotFoundException异常。
    Log.v("StrictMode", "... not supported. Skipping...");  
}  
原文地址:https://www.cnblogs.com/coderwjq/p/7079158.html