App优化 StrictMode 严格模式

归志宁无五亩园,读书本意在元元。这篇文章主要讲述App优化 StrictMode 严格模式相关的知识,希望能为你提供帮助。
StrictMode简介
        StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例。除了主线程,我们还可以在Handler,AsyncTask,AsyncQueryHandler,IntentService等API中使用StrictMode。
示例代码    StrictMode文档

App优化 StrictMode 严格模式

文章图片

检查策略 StrictMode的线程策略主要用于检测磁盘IO和网络访问,而虚拟机策略主要用于检测内存泄漏现象。android已经在磁盘IO访问和网络访问的代码中加入了StrictMode。当监视的线程发生策略的违例时,就可以获得警告,例如写入LogCat,显示一个对话框,闪下屏幕,写入DropBox日志文件,或让应用崩溃。最通常的做法是写入LogCat或让应用崩溃。下面的代码展示了如何使用StrictMode的检查策略:
【App优化 StrictMode 严格模式】
public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()//线程策略 .detectDiskReads()//detect [d??t?kt] vt.查明,发现; 洞察; 侦察,侦查; .detectDiskWrites() .detectNetwork() // or .detectAll() for all detectable problems .penaltyDialog()//penalty [?p?n?lti] n.刑罚; 惩罚; 害处 .penaltyLog() .penaltyDropBox()//DropBox下拉框 .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()//虚拟机策略 .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(); }

2121  1
public void onCreate() {  

2
    if (DEVELOPER_MODE) {  

3
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()   //线程策略

4
                .detectDiskReads()   //detect [d??t?kt] vt.查明,发现; 洞察; 侦察,侦查;

5
                .detectDiskWrites()  

6
                .detectNetwork()  

7
                // or .detectAll() for all detectable problems

8
                .penaltyDialog()   //penalty [?p?n?lti] n.刑罚; 惩罚; 害处

9
                .penaltyLog()  

10
                .penaltyDropBox()   //DropBox下拉框

11
                .build());  

12
       

13
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()   //虚拟机策略

14
                .detectLeakedSqlLiteObjects()  

15
                .detectLeakedClosableObjects()  

16
                .penaltyLog()  

17
                .penaltyDeath()  

18
                .build());  

19
    }  

20
    super.onCreate();  

21
}  



使用方法                  如果不指定检测函数,也可以用detectAll()来替代。penaltyLog()表示将警告输出到LogCat,你也可以使用其他或增加新的惩罚(penalty)函数,例如使用penaltyDeath()的话,一旦StrictMode消息被写到LogCat后应用就会崩溃。具体支持的监视方法见:StrictMode.ThreadPolicy.Builder  与  StrictMode.VmPolicy.Builder。


在正式版本中,我们并不希望使用StrictMode来让用户的应用因为一个警告而崩溃,所以在应用正式发布时,需要移出这些监视。你可以通过删除代码来实现,不过这里提供一个更好的方式来解决这个问题,即使用AndroidMainifest文件中的debuggable属性来实现,代码如下所示:
android:debuggable="true"

11  1
android:debuggable="true"  

PS:可能在gradle中这么配置也行
android { buildTypes { debug { debuggable true } } }

77  1
android {    

2
buildTypes {

3
debug {

4
debuggable true

5
}

6
}

7
}

在代码中,使用方法如下所示:

// Return if this application is not in debug mode if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { // Do StrictMode setup here StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .penaltyLog() .penaltyDeath() .build()); }

99  1
// Return if this application is not in debug mode

2
if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {  

3
    // Do StrictMode setup here  

4
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  

5
      .detectLeakedSqlLiteObjects()  

6
      .penaltyLog()  

7
      .penaltyDeath()  

8
      .build());  

9
}  



实例
  我们在测试代码的主线程中去访问网络,这样就一定会触发StrictMode的线程监测,代码如下所示:

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyDialog() .penaltyLog() .penaltyDropBox() .build()); super.onCreate(savedInstanceState); TextView mTextView = new TextView(this); setContentView(mTextView); InputStream inputStream = null; try { HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com")); HttpEntity httpEntity = httpResponse.getEntity(); if (httpResponse.getStatusLine().getStatusCode() == 200) { inputStream = httpEntity.getContent(); mTextView.setText(new BufferedReader(new InputStreamReader(inputStream)).readLine()); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }

3535  1
public class MainActivity extends Activity {

2
@Override

3
protected void onCreate(Bundle savedInstanceState) {

4
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()

5
.detectDiskReads()

6
.detectDiskWrites()

7
.detectNetwork()

8
.penaltyDialog()

9
.penaltyLog()

10
.penaltyDropBox()

11
.build());

12
super.onCreate(savedInstanceState);

13

14
TextView mTextView = new TextView(this);

15
setContentView(mTextView);

16

17
InputStream inputStream = null;

18
try {

19
HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com"));

20
HttpEntity httpEntity = httpResponse.getEntity();

21
if (httpResponse.getStatusLine().getStatusCode() == 200) {

22
inputStream = httpEntity.getContent();

23
mTextView.setText(new BufferedReader(new InputStreamReader(inputStream)).readLine());

24
}

25
} catch (Exception e) {

26
e.printStackTrace();

27
} finally {

28
try {

29
if (inputStream != null) inputStream.close();

30
} catch (IOException e) {

31
e.printStackTrace();

32
}

33
}

34
}

35
}

运行代码,并将Log信息保存到本地,在Log中,我们可以搜索D/StrictMode关键字,如下所示:
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2 at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1157) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:182) at libcore.io.IoBridge.open(IoBridge.java:480) at java.io.FileInputStream.< init> (FileInputStream.java:76) at java.io.FileInputStream.< init> (FileInputStream.java:103) at android.content.res.HwResources.readDefaultConfig(HwResources.java:1172) at android.content.res.HwResources.loadDrawable(HwResources.java:574) at android.content.res.Resources.getDrawable(Resources.java:809) at android.content.Context.getDrawable(Context.java:403) at com.android.internal.widget.ToolbarWidgetWrapper.setIcon(ToolbarWidgetWrapper.java:321) at com.android.internal.widget.ActionBarOverlayLayout.setIcon(ActionBarOverlayLayout.java:741) at com.android.internal.policy.impl.PhoneWindow.setDefaultIcon(PhoneWindow.java:1661) at android.app.Activity.initWindowDecorActionBar(Activity.java:2174) at android.app.Activity.setContentView(Activity.java:2189) at com.imooc.strictmodetest.MainActivity.onCreate(MainActivity.java:36) at android.app.Activity.performCreate(Activity.java:6102) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) at android.app.ActivityThread.access$1200(ActivityThread.java:165) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5593) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:967) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)

2929  1
D/StrictMode: StrictMode policy violation; ~duration=5131 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=183 violation=2

2
  at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1157)

3
  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:182)

4
  at libcore.io.IoBridge.open(IoBridge.java:480)

5
  at java.io.FileInputStream.< init> (FileInputStream.java:76)

6
  at java.io.FileInputStream.< init> (FileInputStream.java:103)

7
  at android.content.res.HwResources.readDefaultConfig(HwResources.java:1172)

8
  at android.content.res.HwResources.loadDrawable(HwResources.java:574)

9
  at android.

    推荐阅读