StrictMode使用详解

      Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode)。
这个类可以用来帮助开发者改进他们编写的应用,并且提供了各种的策略,这些策略能随时检查和报告开发者开发应用中存在的问题,
比如可以监视那些本不应该在主线程中完成的工作或者其他的一些不规范和不友好的代码。
StrictMode有多种不同的策略,每一种策略又有不同的规则,当开发者违背某个规则时,每个策略都有不同的方法去显示提醒用户:
StrictMode的策略和规则

  目前,有两大类的策略可供使用,一类是关于常用的监控方面的,另外一类是关于VM虚拟机等方面的策略。
StrictMode的线程策略主要用于检测磁盘IO和网络访问,而虚拟机策略主要用于检测内存泄漏现象。Android已经在磁盘IO访问和网络访问的代码中已经加入了StrictMode。
当监视的线程发生策略的违例时,就可以获得警告,例如写入LogCat,显示一个对话框,闪下屏幕,写入DropBox日志文件,或让应用崩溃。
最通常的做法是写入LogCat或让应用崩溃。下面的代码展示了如何使用StrictMode的检查策略:

public void onCreate() {
     if (DEVELOPER_MODE) {
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .penaltyDialog()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
     }
     super.onCreate();
 }

       当应用启用了strictmode模式时,其实跟普通的应用没什么两样,在测试和运行时,跟平时运行普通应用程序一样就可以了。当启用了Strictmode模式时,会监视所有的程序运行情况,当发现出现重大问题或违背策略规则时,会提示用户。下面是当运行启用了strictmode模式的应用时,当发现违背规则时,显示给用户的信息。

在Log中,我们可以搜索D/StrictMode(15454): StrictMode policy violation关键字:

D/StrictMode(15454): StrictMode policy violation; ~duration=461 ms:
 android.os.StrictMode$StrictModeNetworkViolation: policy=55 violation=4
D/StrictMode(15454): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1153)
D/StrictMode(15454): 	at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
D/StrictMode(15454): 	at libcore.io.IoBridge.recvfrom(IoBridge.java:553)
D/StrictMode(15454): 	at java.net.PlainSocketImpl.read(PlainSocketImpl.java:485)
D/StrictMode(15454): 	at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
D/StrictMode(15454): 	at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
D/StrictMode(15454): 	at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
D/StrictMode(15454): 	at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
D/StrictMode(15454): 	at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:161)
D/StrictMode(15454): 	at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:175)
D/StrictMode(15454): 	at org.apache.http.impl.io.ChunkedInputStream.exhaustInputStream(ChunkedInputStream.java:289)
D/StrictMode(15454): 	at org.apache.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:262)
D/StrictMode(15454): 	at org.apache.http.conn.BasicManagedEntity.streamClosed(BasicManagedEntity.java:179)
D/StrictMode(15454): 	at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:266)
D/StrictMode(15454): 	at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:213)
D/StrictMode(15454): 	at com.imooc.strictmodetest.MainActivity.onCreate(MainActivity.java:53)
D/StrictMode(15454): 	at android.app.Activity.performCreate(Activity.java:5976)
D/StrictMode(15454): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
D/StrictMode(15454): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
D/StrictMode(15454): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2371)
D/StrictMode(15454): 	at android.app.ActivityThread.access$800(ActivityThread.java:149)
D/StrictMode(15454): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
D/StrictMode(15454): 	at android.os.Handler.dispatchMessage(Handler.java:102)
D/StrictMode(15454): 	at android.os.Looper.loop(Looper.java:135)
D/StrictMode(15454): 	at android.app.ActivityThread.main(ActivityThread.java:5260)
D/StrictMode(15454): 	at java.lang.reflect.Method.invoke(Native Method)
D/StrictMode(15454): 	at java.lang.reflect.Method.invoke(Method.java:372)
D/StrictMode(15454): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
D/StrictMode(15454): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

Log中可以显示出StrictMode提示的原因,通过这里的TraceLog我们就可以来找到优化的方法。除了在Logcat中查看StrictMode的日志信息,如果你使用了penaltyDropbox()方法,那么你还可以通过如下所示的命令来调用DropBoxManager观察StrictMode日志:

adb shell dumpsys dropbox data_app_strictmode --print
暂停监测
 如果在程序运行中无法避免的会违反StrictMode中的一些定义好的策略,而我们又希望能够暂时忽略这些策略的监视,我们可以使用permitXXXXX方法来暂停这些内容的监测,在做完需要忽略的监测之后,再启用监测,代码如下所示:

StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
        .permitDiskWrites()
        .build());
//doSomethingWriteToDisk();
StrictMode.setThreadPolicy(old);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值