|
StrictMode是Android提供的一個開發(fā)工具,用于檢測一些異常的操作,以便開發(fā)者進(jìn)行修復(fù)。StrictMode可以監(jiān)控以下問題,
- 不應(yīng)該在應(yīng)用主線程中完成的工作,包括磁盤讀寫、網(wǎng)絡(luò)訪問等。
- 內(nèi)存泄露,包括Activity泄露、SQLite泄露、未正確釋放的對象等。
使能StrictMode
通常在Application和Activity的開始處(如onCreate)添加代碼使能StrictMode,
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
開啟StrictMode需要進(jìn)行兩方面的設(shè)置:ThreadPolicy和VmPolicy。兩種策略中以“detect”開頭命名的方法代表需要檢測的問題,以“penalty”開頭命名地 方法代表探測到問題后的處理方式。
- ThreadPolicy為線程方面使用的策略,包括磁盤讀寫檢測,網(wǎng)絡(luò)訪問檢測等。
- VmPolicy為VM相關(guān)的策略,用于檢測內(nèi)存泄露,未釋放的對象等。
兩種策略中使用的主要方法如下,
| ThreadPolicy |
|
| detectAll() |
檢測所有潛在的問題 |
| detectCustomSlowCalls() |
檢測慢速調(diào)用 |
| detectDiskReads() |
檢測磁盤讀操作 |
| detectDiskWrites() |
檢測磁盤寫操作 |
| detectNetwork() |
檢測網(wǎng)絡(luò)操作 |
| detectResourceMismatches() |
檢測定義資源類型和getter調(diào)用之間的不匹配 |
| detectUnbufferedIo() |
檢測未緩存的I/O操作 |
| penaltyDeath() |
檢測到問題后crash整個進(jìn)程 |
| penaltyDeathOnNetwork() |
檢測到問題后crash任何使用網(wǎng)絡(luò)的進(jìn)程 |
| penaltyDialog() |
檢測到問題后彈出對話框 |
| penaltyDropBox() |
檢測到問題后將堆棧和數(shù)據(jù)寫到DropBox中 |
| penaltyFlashScreen() |
檢測到問題后閃爍屏幕 |
| penaltyLog() |
檢測到問題后記錄到系統(tǒng)日志中。 |
| VmPolicy |
|
| detectAll() |
檢測所有潛在的問題 |
| detectActivityLeaks() |
檢測Activity內(nèi)存泄露 |
| detectCleartextNetwork() |
檢測未使用SSL / TLS打包的任何網(wǎng)絡(luò)傳輸 |
| detectContentUriWithoutPermission() |
檢測未設(shè)置讀寫權(quán)限的"content://Uri"傳輸 |
| detectFileUriExposure() |
檢測“file://Uri"傳輸 |
| detectLeakedClosableObjects() |
檢測對象未正常關(guān)閉。 |
| detectLeakedRegistrationObjects() |
檢測BroadcastReceiver或ServiceConnection在Context拆卸時發(fā)生的泄露 |
| detectLeakedSqlLiteObjects() |
檢測SQLite對象未正常關(guān)閉 |
| detectNonSdkApiUsage() |
檢測非Android SDK API的反射用法。 |
| detectUntaggedSockets() |
檢測未使用TrafficStats標(biāo)記的套接字 |
| penaltyDeath() |
檢測到問題后crash整個進(jìn)程 |
| penaltyDeathOnCleartextNetwork() |
檢測到問題后crash任何使用網(wǎng)絡(luò)的進(jìn)程 |
| penaltyDeathOnFileUriExposure() |
當(dāng)“file://Uri"暴露在應(yīng)用之外時,crash整個進(jìn)程 |
| penaltyDropBox() |
檢測到問題后將堆棧和數(shù)據(jù)寫到DropBox中 |
| penaltyLog() |
檢測到問題后記錄到系統(tǒng)日志中。 |
| setClassInstanceLimit(Class klass, int instanceLimit) |
設(shè)置同時在內(nèi)存中存儲一個類實(shí)例的上限。 |
檢查StrictMode的結(jié)果
當(dāng)在策略中設(shè)置penaltyLog()時,可以在系統(tǒng)log中打印相關(guān)log,可以使用”adb logcat -s StrictMode“進(jìn)行查看。例如下面這段log,說明涉嫌違規(guī)的操作是StrickMode:DiskReadViolation,耗時48ms。
D StrictMode: StrictMode policy violation; ~duration=48 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=4390919 violation=2
at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1263)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1039)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:840)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:219)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:268)
at com.gm.android.emojistore.provider.EmojiStoreProvider.handleEtxetQuery(EmojiStoreProvider.java:108)
at android.content.ContentProvider.query(ContentProvider.java:1017)
at android.content.ContentProvider$Transport.query(ContentProvider.java:238)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
當(dāng)在設(shè)備端通過設(shè)置打開嚴(yán)格模式時,出現(xiàn)違規(guī)操作時屏幕會閃爍。
設(shè)置-》開發(fā)人員選項(xiàng)-》監(jiān)控-》啟用嚴(yán)格模式
當(dāng)在策略中設(shè)置penaltyDropBox() 時,出現(xiàn)違規(guī)操作時會在/data/system/dropbox/下生成文件。文件包括system_app_strictmode 和 data_app_strictmode兩種,內(nèi)容包括問題發(fā)生時的堆棧和進(jìn)程相關(guān)信息。
參考文檔:
Android Developer: StrictMode
|