StrictMode 嚴(yán)格模式
開發(fā)者經(jīng)常會(huì)無(wú)意地犯些錯(cuò)誤:在主線程讀寫磁盤、訪問(wèn)網(wǎng)絡(luò),嚴(yán)格模式能夠把幫助開發(fā)者監(jiān)控這些錯(cuò)誤。
注意:嚴(yán)格模式是一種保護(hù)機(jī)制但是并不保證找出所有的磁盤和網(wǎng)絡(luò)訪問(wèn)。因?yàn)閲?yán)格模式經(jīng)常在發(fā)生Binder Call的時(shí)候報(bào)告自己的狀態(tài),所以它是一種盡力而為的機(jī)制。一般地,網(wǎng)絡(luò)和磁盤訪問(wèn)一般走JNI調(diào)用,所以不一定會(huì)觸發(fā)它。還有一點(diǎn),線上的應(yīng)用不應(yīng)該開啟嚴(yán)格模式。
代碼示例:
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
嚴(yán)格模式下的兩種策略
StrictMode.ThreadPolicy(作用于特定線程)
主要監(jiān)控以下內(nèi)容:
Disk Reads 磁盤讀
Disk Writes 磁盤寫
Network access 網(wǎng)絡(luò)訪問(wèn)
Custom Slow Code 自定義的運(yùn)行速度慢的代碼分析
StrictMode.VmPolicy(作用于整個(gè)虛擬機(jī)進(jìn)程的所有線程)
主要監(jiān)控以下內(nèi)容:
內(nèi)存泄露的Activity對(duì)象
內(nèi)存泄露的SQLite對(duì)象
內(nèi)存泄露的釋放的對(duì)象
內(nèi)存泄漏的BroadcastReceiver or ServiceConnection
嚴(yán)格模式監(jiān)控到異常信息觸發(fā)的提示
Log 日志
Death 應(yīng)用退出
DropBox 持久化的、系統(tǒng)級(jí)別的Logcat
測(cè)試
代碼
package com.jinglong.strickmodetest;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
public static final String STRICK_MODE_TEST = "StrickModeTest";
public static final String TAG = STRICK_MODE_TEST + ":" +MainActivity.class.getName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
File externalStorageDirectory = Environment.getExternalStorageDirectory();
if (externalStorageDirectory==null||!externalStorageDirectory.exists()){
Log.d(TAG,"SDCard is not exist");
}else{
//獲取SD卡下的文件或目錄
String[] childrenFiles = externalStorageDirectory.list();
for (int i = 0;i < childrenFiles.length;i++){
File childFile = new File(externalStorageDirectory.getPath(),childrenFiles[i]);
if (childFile.exists()&&childFile.isFile()){
//找到第一個(gè)File
try {
FileReader fr = new FileReader(childFile);
char ch[] = new char[1024] ;
while (fr.read(ch)!=-1){
Log.e(TAG,new String(ch));
}
//為了測(cè)試效果,此處不關(guān)fr
FileWriter fw = new FileWriter(childFile);
fw.write("Hello 璟龍");
fw.flush();
//為了測(cè)試效果,此處不關(guān)fw
break;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
日志
- 第一條日志表示資源沒有關(guān)閉,即IO流未關(guān)閉
- 第二條日志表示在主線程中發(fā)生了磁盤訪問(wèn)的讀操作
07-18 15:05:26.930 10735-10748/com.jinglong.strickmodetest E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
07-18 15:05:26.949 10735-10735/com.jinglong.strickmodetest D/StrictMode: StrictMode policy violation; ~duration=44 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=31 violation=2