標籤:
轉:http://www.blueowls.net/android-strictmode%E4%BB%8B%E7%BB%8D/
/** * enables "strict mode" for testing - should NEVER be used in release builds */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private static void enableStrictMode() { // return if the build is not a debug build if (!BuildConfig.DEBUG) { AppLog.e(T.UTILS, "You should not call enableStrictMode() on a non debug build"); return; } StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .penaltyFlashScreen() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectActivityLeaks() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .detectLeakedRegistrationObjects() // <-- requires Jelly Bean .penaltyLog() .build()); AppLog.w(T.UTILS, "Strict mode enabled"); }
Android平台中(Android 2.3起),新增加了一個新的類,叫StrictMode(android.os.StrictMode)。這個類可以用來協助開發人員改進他們編寫的應用,並且提供了各種的策略,這些策略能隨時檢查和報告開發人員開發應用中存在的問題,比如可以監視那些本不應該在主線程中完成的工作或者其他的一些不規範和不好的代碼。
StrictMode有多種不同的策略,每一種策略又有不同的規則,當開發人員違背某個規則時,每個策略都有不同的方法去顯示提醒使用者。在本文中,將舉例子說明如何使用在Android 中使用 StrictMode。
StrictMode的策略和規則
目前,有兩大類的策略可供使用,一類是關於常用的監控方面的,另外一類是關於VM虛擬機器等方面的策略。常用的監控方面的策略有如下這些:
Disk Reads 磁碟讀
Disk Writes 磁碟寫
Network access 網路訪問
Custom Slow Code 自訂的運行速度慢的程式碼分析
前面三種的意思讀者應該很清楚,就是正如它們的名字所示,分別對磁碟的讀和寫,網路訪問進行監控。而第四種的自訂慢程式碼分析,是僅當訪問調用類的時後才觸發的,可以通過這種方法去監視運行緩慢的代碼。當在主線程中調用時,這些驗證規則就會起作用去檢查你的代碼。比如,當你的應用在下載或者解析大量的資料時,你可以觸發自訂運行速度慢代碼的查詢分析,作用很大。StrictMode可以用於捕捉髮生在應用程式主線程中耗時的磁碟、網路訪問或函數調用,可以協助開發人員使其改進程式,使主線程處理UI和動畫在磁碟讀寫和網路操作時變得更平滑,避免主線程被阻塞的發生。
而VM方面的策略重點關注如下幾類:
記憶體泄露的Activity對象
記憶體泄露的SQLite對象
記憶體泄露的釋放的對象
其中,記憶體泄露的Activity對象和記憶體泄露的SQLite對象都比較好理解,而所謂對關閉對象的檢查,主要是去監那些本該釋放的對象,比如應該調用close()方法的對象。
當開發人員違反某類規則時,每種策略都會有不同的方法令開發人員知道當時的情況。相關的違反情況可以記錄在LogCat中或者儲存在DropBox中(android.os.DropBox)服務中。而常用監控類的策略還會在當違規情況發生時顯示相關的對話方塊和當時的上下文環境,所有的這些都為了能讓開發人員儘快地瞭解程式的瑕疵,以提交程式的品質。
第一步 啟用strictmode
為了能在應用中啟用和配置StrictMode,開發人員最好儘可能在應用程式的生命週期的早段使用,方法是調用StrictMode的方法setThreadPolicy。當使用常用監控類的時候,一個最好的調用時機,是在應用中入口和activities被調用前進行。比如在一個應用程式中,可以把代碼放在啟動Activity類的onCreate()方法中,下面是一個程式碼範例,啟用了當前情況下的所有策略及規則,當程式中出現違背常用的規則時,將會顯示相關的提示資訊視窗:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .penaltyDialog() ////列印logcat,當然也可以定位到dropbox,通過檔案儲存相應的log .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll() .penaltyLog() .build());
當然,以上代碼只應在未發布上線的測試版本的應用中運行以方便監視相關的運行情況,當在生產版本上時不應該啟用strictmode。因此,最佳的代碼實踐應該為如下的樣子:
public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); } super.onCreate(); }
public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); } super.onCreate(); } 這裡,執行了一些向磁碟快速讀寫的操作,最後又重新啟用了這些規則。StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy(); StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old) .permitDiskWrites() .build()); doCorrectStuffThatWritesToDisk(); StrictMode.setThreadPolicy(old);
StrictMode是一個十分有用的類,它可以很方便地應用於檢查Android應用程式的效能和存在的問題。當開啟這個模式後,開發人員能很好地檢查應用中存在的潛在問題,更多的請參考Android文檔中的相關API說明。
Android StrictMode介紹