Android 2.3提供一個稱為嚴苛模式(StrictMode)的調試特性,Google稱該特性已經使數百個Android上的Google應用程序受益。那它都做什么呢?它將報告與線程及虛擬機相關的策略違例。一旦檢測到策略違例(policy violation),你將獲得警告,其包含了一個棧trace顯示你的應用在何處發(fā)生違例。你可以強制用警告代替崩潰(crash),也可以僅將警告計入日志,讓你的應用繼續(xù)執(zhí)行。策略的細節(jié)尚難確定,可以期待隨Android的成熟Google將增加更多策略。
主要采用采用ThreadPolicy(線程策略)和VmPolicy(Vm策略)進行檢測,各策略檢測內容如下:
ThreadPolicy 線程策略檢測的內容有
- 自定義的耗時調用 使用 detectCustomSlowCalls() 開啟
- 磁盤讀取操作 使用 detectDiskReads() 開啟
- 磁盤寫入操作 使用 detectDiskWrites() 開啟
- 網絡操作 使用 detectNetwork() 開啟
- 資源類型不匹配 使用detectResourceMismatches() 開啟 android 23 開始增加
VmPolicy 虛擬機策略檢測的內容有
- Activity泄露 使用 detectActivityLeaks() 開啟
- 未關閉的Closable對象泄露 使用 detectLeakedClosableObjects() 開啟
- 泄露的Sqlite對象 使用 detectLeakedSqlLiteObjects() 開啟
- 網絡流量監(jiān)控 使用 detectCleartextNetwork() android 23增加
- 廣播或者服務等未注銷導致泄漏 使用 detectLeakedRegistrationObjects()開啟 android 23增加
- 文件uri暴露 使用detectFileUriExposure() android增加
要注意anroid 23新增加的幾個策略檢測
- android 23 以后傳遞軟件包網域外的 file://URI 可能給接收器留下無法訪問的路徑。 因此,嘗試傳遞 file://URI 會觸發(fā) FileUriExposedException。 分享私有文件內容的推薦方法是使用 FileProvider。
如果不使用FileProvider時,而且開啟了嚴格模式,則必須關閉detectFileUriExposure() - 建議在使用的直接調用detectAll(),而不是依次開啟檢測具體的策略
- 而且嚴格模式StrictMode建議在調試模式中開啟,防止影響正常運行
StrictMode具體使用:
StrictMode建議在application 的onCreate()的方法中調用;
StrictModeHelper.setPolicy(BuildConfig.DEBUG);
調試時才開啟,而且利用BuildConfig屬性是否app在調試模式
public class StrictModeHelper {
public static void setPolicy(Boolean isDebug) {
if (isDebug && Build.VERSION.SDK_INT >= 9) {
setThreadPolicy();
setVmPolicy();
}
}
//線程策略檢測
private static void setThreadPolicy() {
StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder()
.detectAll() //detectAll() 檢測下述所有
// .detectCustomSlowCalls() //自定義耗時調用
// .detectDiskReads() //磁盤讀取操作
// .detectDiskWrites() //磁盤寫入操作
// .detectNetwork() //網絡操作
// .detectResourceMismatches() //資源類型不匹配 android 23增加
.penaltyLog(); //打印logcat,當然也可以定位到dropbox,通過文件保存相應的log
StrictMode.setThreadPolicy(builder.build());
}
//虛擬機策略檢測
private static void setVmPolicy() {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder()
.detectAll() //檢測下述所有
// .detectActivityLeaks() //Activity泄漏
// .detectLeakedClosableObjects() //未關閉Closable對象泄漏
// .detectLeakedSqlLiteObjects() //SqlLite對象泄漏
// .detectCleartextNetwork() //網絡流量監(jiān)控 android 23增加
// .detectLeakedRegistrationObjects() //廣播或者服務等未注銷導致泄漏 android 23增加
// .detectFileUriExposure() //文件uri暴露 android增加
.penaltyLog(); //打印logcat,當然也可以定位到dropbox,通過文件保存相應的log
StrictMode.setVmPolicy(builder.build());
}
}