大家好,又见面了,我是你们的朋友全栈君。
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以下
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/133510.html原文链接:https://javaforall.cn