StrictMode总结
Android 2.3提供一个称为严苛模式(StrictMode)的调试特性,Google称该特性已经使数百个Android上的Google应用程序受益。
首先先整体介绍:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()//线程策略(ThreadPolicy).detectDiskReads()//检测在UI线程读磁盘操作.detectDiskWrites()//检测UI线程写磁盘操作.detectCustomSlowCalls()//发现UI线程调用的哪些方法执行得比较慢.detectResourceMismatches()//最低版本为API23 发现资源不匹配.detectNetwork() //检测在UI线程执行网络操作.penaltyDialog()//一旦检测到弹出Dialog.penaltyDeath()//一旦检测到应用就会崩溃.penaltyFlashScreen()//一旦检测到应用将闪屏退出 有的设备不支持.penaltyDeathOnNetwork()//一旦检测到应用就会崩溃.penaltyDropBox()//一旦检测到将信息存到DropBox文件夹中 data/system/dropbox.penaltyLog()//一旦检测到将信息以LogCat的形式打印出来.permitDiskReads()//允许UI线程在磁盘上读操作.build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()//虚拟机策略(VmPolicy).detectActivityLeaks()//最低版本API11 用户检查 Activity 的内存泄露情况.detectCleartextNetwork()//最低版本为API23 检测明文的网络.detectFileUriExposure()//最低版本为API18 检测file://或者是content://.detectLeakedClosableObjects()//最低版本API11 资源没有正确关闭时触发.detectLeakedRegistrationObjects()//最低版本API16 BroadcastReceiver、ServiceConnection是否被释放.detectLeakedSqlLiteObjects()//最低版本API9 资源没有正确关闭时回触发.setClassInstanceLimit(MyClass.class, 2)//设置某个类的同时处于内存中的实例上限,可以协助检查内存泄露.penaltyLog()//与上面的一致.penaltyDeath().build());
一 线程策略
detectDiskReads()/detectDiskWrites操作示例:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskWrites().detectDiskReads().penaltyLog().build());strictReads();}private void strictReads(){File file = new File(Environment.getExternalStorageDirectory().getPath()+"/note.txt");FileInputStream inputStream = null;int r = -1;try {inputStream = new FileInputStream(file);while((r = inputStream.read()) != -1){}} catch (Exception e) {e.printStackTrace();}finally {if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}}
detectCustomSlowCalls操作示例:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectCustomSlowCalls().penaltyLog().build());showCustomSlowCallFlag();showCustomSlowCall();}private void showCustomSlowCallFlag(){StrictMode.noteSlowCall("This is Andly");SystemClock.sleep(10002);}private void showCustomSlowCall(){SystemClock.sleep(10002);}
Log:(只有作了标记得才会打印log)
detectResourceMismatches操作示例:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectResourceMismatches().penaltyLog().build());showResourceMismatches();}private void showResourceMismatches() {TypedArray ta = getResources().obtainTypedArray(R.array.icons);int a = ta.getInt(0,0);}
这个没有打印log,不知道为什么。。
detectNetwork操作示例:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectNetwork().penaltyLog().build());strictNetWork();}private void strictNetWork(){try {URL url = new URL("http://www.baidu.com");HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.connect();httpURLConnection.setRequestMethod("GET");httpURLConnection.setReadTimeout(3000);httpURLConnection.setConnectTimeout(5000);int code = httpURLConnection.getResponseCode();} catch (Exception e) {e.printStackTrace();}}
log:
对于线程策略剩下的比较简单就不多说,然后介绍一下:使用penaltyDropBox想要看文件得信息只需要输入:
adb shell dumpsys dropbox (这里写data/system/dropbox目录下文件的名字) --print
二 VM策略
detectActivityLeaks操作示例:
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectActivityLeaks().penaltyLog().penaltyDropBox().build());new Thread(new Runnable() {@Overridepublic void run() {SystemClock.sleep(1000);}}).start();}
log:
log上面显示,实例创建了2个但是限制的是一个
detectLeakedClosableObjects操作示例:
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedClosableObjects().penaltyLog().penaltyDropBox().build());leakedClosableObj();}private void leakedClosableObj() {File newxmlfile = new File(Environment.getExternalStorageDirectory(), "/note.txt");try {newxmlfile.createNewFile();FileWriter fw = new FileWriter(newxmlfile);fw.write("Andly");//fw.close();} catch (IOException e) {e.printStackTrace();}}
setClassInstanceLimit操作示例:
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().setClassInstanceLimit(LimitClass.class, 2).penaltyLog().penaltyDropBox().build());classInstanceLimit();}private void classInstanceLimit() {classList.add(new LimitClass());classList.add(new LimitClass());classList.add(new LimitClass());classList.add(new LimitClass());classList.add(new LimitClass());classList.add(new LimitClass());}
log:
detectLeakedRegistrationObjects操作示例:
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedRegistrationObjects().penaltyLog().penaltyDropBox().build());leakeRegistion();}private void leakeRegistion() {receiver = new myReceive();IntentFilter filter = new IntentFilter();filter.addAction("com.andly.broadcast");registerReceiver(receiver,filter);}
log:
考虑倒关于版本兼容问题,因为按照上面的写法在2.3以下系统是没有问题的,但是在2.3以上的话,就会出错,所以应该采用以下方式来处理
try {Class clazz = Class.forName("android.os.StrictMode");ApplicationInfo info = getApplicationInfo();if((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0){//可以使用严苛模式}else{//不可使用严苛}} catch (ClassNotFoundException e) {//StrictMode类不可用 用这种方法来判断是否再Android2.3以下}