您的位置:首页 > 其它

StrictMode总结

2016-05-10 09:32 507 查看
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() {
@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();
}
}

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以下
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: