`
he91_com
  • 浏览: 375476 次
文章分类
社区版块
存档分类
最新评论

严苛模式(StrictMode)

 
阅读更多
Android 2.3提供一个称为严苛模式(StrictMode)的调试特性,Google称该特性已经使数百个Android上的Google应用程序受益。那它都做什么呢?它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例(policy violation),你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例。你可以强制用警告代替崩溃(crash),也可以仅将警告计入日志,让你的应用继续执行。策略的细节尚难确定,可以期待随Android的成熟Google将增加更多策略。

目前有2种策略可用,第一个和线程相关,它主要针对主线程(或UI线程)。由于在主线程中读写磁盘和进行网络访问都不是好的做法,Google已经在磁盘和网络代码中添加了严苛模式(StrictMode)钩子(hook)。如果你对某个线程打开严苛模式(StrictMode),当那个线程进行磁盘和网络访问,你将获得警告。你可以选择警告方式。一些违例包含用户慢速调用(custom slow calls 这么翻译行吗?),磁盘读写,网络访问。你能选择将警告写入LogCat,显示一个对话框,闪下屏幕,写入DropBox日志文件,或让应用崩溃。最通常的做法是写入LogCat或让应用崩溃。


写程序时,你应该始终假定下列两种情况:

网络很慢(你正在试图连接的服务器甚至可能没有响应);

文件系统的访问速度很慢。

结论就是,不应该在主线程内进行网络操作或访问文件系统,因为缓慢的操作会拖累系统的响应能力。虽然在开发环境中,你可能永远不会遇到任何网络问题或任何文件系统的性能问题,但用户可能不像你那么幸运。

注意SD卡并不都具有相同“速度”,如果应用在很大程度上依赖外部存储设备的性能,那么你应该确保在来自不同制造商的各种SD卡上测试过你的应用。

Android有实用工具来帮助应用检测这类缺陷。它提供的StrictMode是检测不良行为的良好工具。通常情况下,在应用启动时,即当onCreate()被调用时,启用StrictMode,如代码清单1-15所示。

在应用中启用StrictMode

public class MyApplication extends Application {
    @Override
    public void onCreate () {
        super.onCreate();

        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
        .detectCustomSlowCalls()// API等级11,使用StrictMode.noteSlowCode
        .detectDiskReads()
        .detectDiskWrites()
        .detectNetwork()
        .penaltyLog()
        .penaltyFlashScreen()// API等级11
        .build());

         // 其实和性能无关,但如果使用StrictMode,最好也定义VM策略
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
         .detectLeakedSqlLiteObjects()
         .detectLeakedClosableObjects()// API等级11
         .setClassInstanceLimit(Class.forName("com.apress.proandroid.SomeClass", 100)// API等级11
         .penaltyLog()
         .build());
      }
}


StrictMode是Android 2.3引入的,在Android 3.0中加入了更多的功能,所以应该确保选择了正确的Android版本,让代码跑在适当的Android平台上,如代码清单1-12所示。

Android 3.0中引入的需要特别留意的方法包括detectCustomSlowCall()和noteSlowCall(),它们都是用来检测应用中执行缓慢的代码或潜在缓慢的代码。代码清单1-16说明了如何将代码标记为潜在缓慢的代码。

代码清单1-16 标记潜在缓慢的代码

public class Fibonacci {
    public static BigInteger computeRecursivelyWithCache(int n) {
       StrictMode.noteSlowCall("computeRecursivelyWithCache");// 消息可以带任何信息
         SparseArray<BigInteger> cache = new SparseArray<BigInteger>();
         return computeRecursivelyWithCache(n, cache);
     }
     ...
}


public class Fibonacci {
    public static BigInteger computeRecursivelyWithCache(int n) {
       StrictMode.noteSlowCall("computeRecursivelyWithCache");// 消息可以带任何信息
         SparseArray<BigInteger> cache = new SparseArray<BigInteger>();
         return computeRecursivelyWithCache(n, cache);
     }
     ...
}



从主线程调用computeRecursivelyWithCache执行时间过长,如果StrictMode Thread 策略配置为检测缓慢调用时,会出现如下日志:

StrictMode policy violation; ~duration=21121 ms:
android.os.StrictMode$StrictModeCustomViolation: policy=31 violation=8 msg=computeRecursivelyWithCache

StrictMode policy violation; ~duration=21121 ms:
android.os.StrictMode$StrictModeCustomViolation: policy=31 violation=8 msg=computeRecursivelyWithCache

Android提供了一些辅助方法,可以在主线程里进行临时磁盘读写,如代码

StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();


 修改线程策略,临时允许磁盘读取

StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
 // 从磁盘读取数据
 StrictMode.setThreadPolicy(oldPolicy);


目前没有临时允许网络访问的方法,但实在没有理由在主线程中允许这种访问,即使是暂时的,也没有合适的方式知道访问是否很快。有人可能会说,也没有合理的方式知道磁盘访问将是否是快速的,但那是另一场争论。

注意只在开发阶段启用StrictMode,发布应用时,记得要禁用它。如果你使用detectAll()方法去建立策略总是可行的,那将来更可行,未来的Android版本会检测出更多的不良行为。



分享到:
评论

相关推荐

    Android严苛模式StrictMode使用详解

    StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题,以达到提升应用响应能力的目的

    详解Android StrictMode严格模式的使用方法

    Android 2.3提供一个称为严苛模式StrictMode的调试特性,Google称该特性已经使数百个Android上的Google应用程序受益。那它都做什么呢?它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例policy violation,...

    Android StrictMode运行流程(推荐)

    什么是 StrictMode(严苛模式) strictmode是android在 API9后引入的检测影响app运行流畅性的一种机制,例如我们都知道的主线程中不允许有网络操作这条规则就是严苛模式规则的一种. strictmode.java 这个类中设定了许多...

    strictMode介绍

    很全的,不错的strictMode 的简介

    StrictModeUtils.java

    严苛模式主要检测两大问题,一个是线程策略,即TreadPolicy,另一个是VM策略,即VmPolicy。 常见用法 严格模式的开启可以放在Application或者Activity以及其他组件的onCreate方法。为了更好地分析应用中的问题,...

    android strictmode_dropbox_tombstone介绍

    介绍android 上运行时调试工具,strictmode,dropbox和tombstone

    Android性能调优利器StrictMode应用分析

    StrictMode意思为严格模式,是用来检测程序中违例情况的开发者工具。最常用的场景就是检测主线程中本地磁盘和网络读写等耗时的操作。这篇文章给大家介绍Android性能调优利器StrictMode应用分析,感兴趣的朋友一起看...

    Android HttpURLConnection中 StrictMode同时支持3.0以上和3.0以下版本

    Android在使用HttpURLConnection时常常遇到无法同时支持3.0和2.X版本的问题,本源码演示了如何用同一个包支持两个版本的问题。

    Eclipse错误解决方法

    当出现提示说: Call requires API level 9 (current min is 8): android.os.StrictMode#setThrea 也就是说版本低

    深入理解javascript严格模式(Strict Mode)

    Strict mode是JavaScript1.8.5引进的技术,但还没有浏览器确实可靠的实现了严格模式,所以使用时要小心并且多测试。Strict mode可以应用于整个脚本,也可以适合于单个函数。

    web前端react框架

    是前端很火的框架,包含jsx使用规则,严格模式&lt;React.StrictMode&gt;,函数组件,类组件的区别,super是否添加参数问题,setState进行异步修改状态,以及状态提升,类组件生命周期(废弃掉的),组件之间的优化,受控和...

    Android代码-用 RxJava 实现 EventBus 。

    StrictMode 宽泛匹配模式 严格匹配模式 StickyEvent @BusEvent 实现教程 关于作者 联系方式 开源项目 License 基于发布订阅(Pub/Sub)模式的一个事件消息库,使用通用的 register(target), unregister(target...

    Android 7.0行为变更 FileUriExposedException解决方法

    Android 7.0行为变更 ...对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriE

    JianDan-高仿煎蛋客户端.zip

    及加载本地缓存图片的实现RecyclerView自动加载、加载完成回调,以及item进入动画多楼层回复自定义控件的实现严格模式(StrictMode)的设置及用法使用GreenDao对数据进行本地缓存对网络状态的实时检测对UIL的个性化...

    web-audio-hooks-issue:用于调试React StrictMode与useAudioContext的交互

    在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何棉绒错误。 npm test 在交互式监视模式下启动测试运行器。 有关更多信息,请参见关于的部分。 ...

    Android项目源码煎蛋网非官方客户端项目源码.zip

    严格模式(StrictMode)的设置及用法 使用GreenDao对数据进行本地缓存 对网络状态的实时检测 对UIL的个性化设置、封装和基本使用 使用LeakCanary检测内存泄露 优化的功能 添加加载等待动画 添加加载失败提示 ...

Global site tag (gtag.js) - Google Analytics