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(); } } } }
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)
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(); } }
对于线程策略剩下的比较简单就不多说,然后介绍一下:使用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() { @Override public 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(); } }
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以下 }