严苛模式(StrictMode)
??? 眼下有2種策略可用,第一個(gè)和線程相關(guān),它主要針對(duì)主線程(或UI線程)。因?yàn)樵谥骶€程中讀寫(xiě)磁盤(pán)和進(jìn)行網(wǎng)絡(luò)訪問(wèn)都不是好的做法,Google已經(jīng)在磁盤(pán)和網(wǎng)絡(luò)代碼中加入了嚴(yán)苛模式(StrictMode)鉤子(hook)。假設(shè)你對(duì)某個(gè)線程打開(kāi)嚴(yán)苛模式(StrictMode),當(dāng)那個(gè)線程進(jìn)行磁盤(pán)和網(wǎng)絡(luò)訪問(wèn),你將獲得警告。你能夠選擇警告方式。一些違例包括用戶(hù)慢速調(diào)用(custom slow calls 這么翻譯行嗎?),磁盤(pán)讀寫(xiě),網(wǎng)絡(luò)訪問(wèn)。你能選擇將警告寫(xiě)入LogCat,顯示一個(gè)對(duì)話框,閃下屏幕,寫(xiě)入DropBox日志文件,或讓?xiě)?yīng)用崩潰。最通常的做法是寫(xiě)入LogCat或讓?xiě)?yīng)用崩潰。列表2-9顯示了一個(gè)為線程策略設(shè)置嚴(yán)苛模式(StrictMode)的樣例。
列表2-9 設(shè)置嚴(yán)苛模式(StrictMode)的線程策略
view plainprint???? Builder類(lèi)使得設(shè)置變得非常easy,Builder函數(shù)定義全部策略都返回Builder對(duì)象,從而這些函數(shù)能像列表2-9那樣串連在一起。最后調(diào)用build()函數(shù)返回一個(gè)ThreadPolicy對(duì)象作為StrictMode對(duì)象的setThreadPolicy()函數(shù)的參數(shù)。注意到setThreadPolicy()是一個(gè)靜態(tài)函數(shù),因此不須要實(shí)例化StrictMode對(duì)象。在內(nèi)部,setThreadPolicy()將對(duì)當(dāng)前線程應(yīng)用該策略。假設(shè)不指定檢測(cè)函數(shù),也能夠用detectAll()來(lái)替代。penaltyLog()表示將警告輸出到LogCat,你也能夠使用其它或添加新的懲處(penalty)函數(shù),比如使用penaltyDeath()的話,一旦StrictMode消息被寫(xiě)到LogCat后應(yīng)用就會(huì)崩潰。
??? 你不須要頻繁打開(kāi)嚴(yán)苛模式(StrictMode),你能夠在主活動(dòng)的onCreate()函數(shù)中打開(kāi)它,你也能夠在Application派生類(lèi)的OnCreate()函數(shù)中設(shè)置嚴(yán)苛模式(StrictMode)。線程中執(zhí)行的不論什么代碼都能夠設(shè)置嚴(yán)苛模式(StrictMode),但你的確僅僅須要設(shè)置一次,一次就夠了。
??? 類(lèi)似于線程策略(ThreadPolicy),嚴(yán)苛模式(StrictMode)有虛擬機(jī)策略(VmPolicy)。虛擬機(jī)策略(VmPolicy)能檢查內(nèi)存泄漏,譬如,當(dāng)關(guān)閉一個(gè)SQLite對(duì)象前的完結(jié)操作,或其它不論什么類(lèi)似可關(guān)閉對(duì)象在關(guān)閉前的完結(jié)操作。虛擬機(jī)策略(VmPolicy)由一個(gè)類(lèi)似的Builder類(lèi)創(chuàng)建,如列表2-10所看到的。和線程策略(ThreadPolicy)不同的是,虛擬機(jī)策略(VmPolicy)不能通過(guò)一個(gè)對(duì)話框提供警告。
列表2-10 設(shè)置嚴(yán)苛模式(StrictMode)的虛擬機(jī)策略
??? 由于設(shè)置發(fā)生在線程中,嚴(yán)苛模式(StrictMode)甚至能在從一個(gè)對(duì)象到還有一個(gè)對(duì)象的控制流中找到違例事件。當(dāng)違例發(fā)生,你會(huì)驚奇地注意到代碼正執(zhí)行于主線程,而棧trace將幫助你發(fā)現(xiàn)它怎樣發(fā)生。于是你能單步調(diào)試解決這個(gè)問(wèn)題,或是將代碼移到它自己的后臺(tái)線程,或是就保持原來(lái)的處理方式。這都取決與你。當(dāng)然,你可能希望適時(shí)關(guān)閉嚴(yán)苛模式(StrictMode),當(dāng)你的程序作為產(chǎn)品公布時(shí),你可不希望它僅為了一個(gè)警告在你的用戶(hù)手里崩潰。
??? 有兩個(gè)方法能夠關(guān)閉嚴(yán)苛模式(StrictMode),最直接的就是移除對(duì)應(yīng)代碼,但這樣做不利于持續(xù)開(kāi)發(fā)的產(chǎn)品。你通常能夠定義一個(gè)應(yīng)用級(jí)別布爾變量來(lái)測(cè)試是否須要調(diào)用嚴(yán)苛模式(StrictMode)代碼。在公布產(chǎn)品前將這個(gè)值定義為FALSE。更優(yōu)雅的方式是利用調(diào)試模式(debug mode)的特點(diǎn),在AndroidManifest.xml中定義這個(gè)布爾變量。<application>字段的屬性之中的一個(gè)是android:debuggable,其義自明。列表2-11給出了利用該特性的控釋方法。
列表2-11 僅在調(diào)試模式設(shè)置嚴(yán)苛模式(StrictMode)
??? 嚴(yán)苛模式(StrictMode)非常不錯(cuò),只是在Android 2.3之前的版本號(hào)上該模式不工作。為了避免這個(gè)問(wèn)題,你要在StrictMode對(duì)象還不存在的時(shí)候就驗(yàn)證版本號(hào)是否在Android2.3及以上。你能利用反射技術(shù)(reflection),當(dāng)嚴(yán)苛模式(StrictMode)函數(shù)有效時(shí)間接調(diào)用它,反之不去調(diào)用。方法非常easy,你能按列表2-12中的代碼處理
列表2-12? 利用反射技術(shù)(reflection)調(diào)用嚴(yán)苛模式(StrictMode)
??? 某些時(shí)候你不希望報(bào)告全部違例。那在主線程之外的其它線程中設(shè)置嚴(yán)苛模式(StrictMode)非常不錯(cuò)。譬如,你須要在正在監(jiān)視的線程中進(jìn)行磁盤(pán)讀取。此時(shí),你要么不去調(diào)用detectDiskReads(),要么在調(diào)用detectAll()之后跟一個(gè)permitDiskReads()。類(lèi)似同意函數(shù)也適用于其它操作。但要是你要在Anroid2.3之前版本號(hào)上做這些事,有辦法嗎?當(dāng)然有。
??? 當(dāng)應(yīng)用中嚴(yán)苛模式(StrictMode)無(wú)效,假設(shè)你試圖訪問(wèn)它,將拋出一個(gè)VerifyError異常。假設(shè)你將嚴(yán)苛模式(StrictMode)封裝在一個(gè)類(lèi)里,并捕捉這個(gè)錯(cuò)誤,當(dāng)嚴(yán)苛模式(StrictMode)無(wú)效時(shí),你能忽略它。列表2-13顯示一個(gè)簡(jiǎn)單的嚴(yán)苛模式(StrictMode)封裝類(lèi)StrictModeWrapper。列表2-14顯示了怎樣在你的應(yīng)用中使用這個(gè)封裝類(lèi)。
列表 2–13 在Anroid2.3之前版本號(hào)建立嚴(yán)苛模式(StrictMode)封裝類(lèi)
列表 2–14? 在Anroid2.3之前版本號(hào)調(diào)用嚴(yán)苛模式(StrictMode)封裝類(lèi)
view plainprint?
//假設(shè)考慮到關(guān)于版本號(hào)兼容問(wèn)題,由于依照上面的寫(xiě)法在2.3下面系統(tǒng)是沒(méi)有問(wèn)題的,可是在2.3以上的話,就會(huì)出錯(cuò),所以應(yīng)該採(cǎi)用下面方式來(lái)處理:
@SuppressLint("NewApi")public static void init(Context context) {// check if android:debuggable is set to trueint appFlags = context.getApplicationInfo().flags;if ((appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {try {//Android 2.3及以上調(diào)用嚴(yán)苛模式Class sMode = Class.forName("android.os.StrictMode");Method enableDefaults = sMode.getMethod("enableDefaults");enableDefaults.invoke(null);} catch (Exception e) {// StrictMode not supported on this device, puntLog.v("StrictMode", "... not supported. Skipping...");}/** StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()* .detectDiskReads() .detectDiskWrites() .detectNetwork()* .penaltyLog() .build()); StrictMode.setVmPolicy(new* StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects()* .penaltyLog() .penaltyDeath() .build());*/}}
總結(jié)
以上是生活随笔為你收集整理的严苛模式(StrictMode)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java解析XML获取城市代码
- 下一篇: 从零开始-android 4.2之旅