http://blog.csdn.net/t12x3456/article/details/8877679

原创 2013年12月04日 22:45:19
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

  1. public class MyApplication extends Application {  
  2.     @Override  
  3.     public void onCreate () {  
  4.         super.onCreate();  
  5.   
  6.         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()  
  7.         .detectCustomSlowCalls()// API等级11,使用StrictMode.noteSlowCode  
  8.         .detectDiskReads()  
  9.         .detectDiskWrites()  
  10.         .detectNetwork()  
  11.         .penaltyLog()  
  12.         .penaltyFlashScreen()// API等级11  
  13.         .build());  
  14.   
  15.          // 其实和性能无关,但如果使用StrictMode,最好也定义VM策略  
  16.          StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  
  17.          .detectLeakedSqlLiteObjects()  
  18.          .detectLeakedClosableObjects()// API等级11  
  19.          .setClassInstanceLimit(Class.forName("com.apress.proandroid.SomeClass"100)// API等级11  
  20.          .penaltyLog()  
  21.          .build());  
  22.       }  
  23. }  


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

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

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

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



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

  1. StrictMode policy violation; ~duration=21121 ms:  
  2. 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提供了一些辅助方法,可以在主线程里进行临时磁盘读写,如代码

  1. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();  


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

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


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

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




http://blog.csdn.net/t12x3456/article/details/9099209



http://blog.csdn.net/zhshulin/article/details/37956105

使用SSM(Spring、SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方。之前没有记录SSM整合...
  • u014205268
  • u014205268
  • 2016年06月26日 17:06
  • 381

http://blog.csdn.net/t12x3456/article/details/9221611

1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClie...
  • qq_15628289
  • qq_15628289
  • 2015年11月13日 20:13
  • 312

转载自:http://blog.csdn.net/lmj623565791/article/details/24015867

1、请解释下在单线程模型中Message,Handler,Message Queue,Looper之间的关系。 拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个...
  • zhi_liyan
  • zhi_liyan
  • 2015年02月10日 10:38
  • 718

http://m.blog.csdn.net/article/details?id=46348827

1.EraseBk()函数不响应,没有加初始化函数. 2.加载图片是白板,初始化函数里的语句有问题. 3.子窗口在父窗口外面,或者移子窗口位置大小子窗口不听话,是因为子窗口属性没有设置为Child...
  • suixinger1
  • suixinger1
  • 2016年10月10日 15:29
  • 6430

Centos7在虚拟机中连接网络及静态IP设置

本文转载自:http://blog.csdn.net/a785975139/article/details/53023590 最近在VMware虚拟机里玩Centos,装好后发现上不了网。经过一...
  • qq_30770095
  • qq_30770095
  • 2018年01月25日 09:04
  • 132

http://blog.csdn.net/ithomer/article/details/6688883

android中获取屏幕的长于宽,参考了网上有很多代码,但结果与实际不符,如我的手机是i9000,屏幕大小是480*800px,得到的结果却为320*533 结果很不靠谱,于是自己写了几行代码,亲测...
  • liyong625175856
  • liyong625175856
  • 2014年06月11日 14:33
  • 777

Winform下KeyDown,KeyPress,KeyUp事件的总结

几篇将的比较好的文章: http ://blog.csdn.net/simpkan/article/details/6087727 http://blog.csdn.net/xiash...
  • anlidengshiwei
  • anlidengshiwei
  • 2014年06月25日 17:23
  • 938

移动互联周考面试题 http://blog.csdn.net/w00w12l/article/details/8143591?locationNum=14&fps=1

这是我的周考面试题 需要把面试题好好复习下 这样才会在工作有个好的发展 http://blog.csdn.net/w00w12l/article/details/8143591?locati...
  • hanguomingxing
  • hanguomingxing
  • 2017年07月24日 11:50
  • 399

http://blog.csdn.net/shootyou/article/details/6093562

http://blog.csdn.net/shootyou/article/details/6093562   Nginx介绍和安装 一个简单的配置文件 模块介绍 ...
  • ywh147
  • ywh147
  • 2013年03月18日 18:12
  • 4706

http://blog.csdn.net/wgwxf/article/details/7804027

转载自:http://blog.csdn.net/wgwxf/article/details/7804027 本人测试可行,dll下载位置,注意是64位的:http://download.c...
  • memray
  • memray
  • 2012年12月01日 08:59
  • 2730
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:http://blog.csdn.net/t12x3456/article/details/8877679
举报原因:
原因补充:

(最多只允许输入30个字)