关键词:
StrictMode简介
StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例。除了主线程,我们还可以在Handler,AsyncTask,AsyncQueryHandler,IntentService等API中使用StrictMode。
检查策略
StrictMode的线程策略主要用于检测磁盘IO和网络访问,而虚拟机策略主要用于检测内存泄漏现象。Android已经在磁盘IO访问和网络访问的代码中加入了StrictMode。当监视的线程发生策略的违例时,就可以获得警告,例如写入LogCat,显示一个对话框,闪下屏幕,写入DropBox日志文件,或让应用崩溃。最通常的做法是写入LogCat或让应用崩溃。下面的代码展示了如何使用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();
}
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();
}
使用方法
如果不指定检测函数,也可以用detectAll()来替代。penaltyLog()表示将警告输出到LogCat,你也可以使用其他或增加新的惩罚(penalty)函数,例如使用penaltyDeath()的话,一旦StrictMode消息被写到LogCat后应用就会崩溃。具体支持的监视方法见:StrictMode.ThreadPolicy.Builder 与 StrictMode.VmPolicy.Builder。
在正式版本中,我们并不希望使用StrictMode来让用户的应用因为一个警告而崩溃,所以在应用正式发布时,需要移出这些监视。你可以通过删除代码来实现,不过这里提供一个更好的方式来解决这个问题,即使用AndroidMainifest文件中的debuggable属性来实现,代码如下所示:
android:debuggable="true"
android:debuggable="true"
PS:可能在gradle中这么配置也行
android {
buildTypes {
debug {
debuggable true
}
}
}
android {
buildTypes {
debug {
debuggable true
}
}
}
在代码中,使用方法如下所示:
// 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());
}
// 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());
}
实例
我们在测试代码的主线程中去访问网络,这样就一定会触发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();
}
}
}
}
public class MainActivity extends Activity {
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();
}
}
}
}
运行代码,并将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)
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.react16.13.1开启严格模式会触发两次render
看代码ReactDOM.render(<React.StrictMode><App/></React.StrictMode>,document.getElementById(‘root‘)); 这时候组件里的render()会执行两次importReactfrom‘react‘;exportdefaultclassAboutextendsReact.Compo 查看详情
什么是“严格模式”,它是如何使用的?
...严格模式”,它是如何使用的?【英文标题】:Whatis"strictmode"andhowisitused?【发布时间】:2012-01-2821:37:04【问题描述】:我一直在查看MozillaDeveloperNetwork上的JavaScript参考资料,发现了一个名为"strictmode"的东西。我读... 查看详情
[react]react的严格模式有什么用处?(代码片段)
[react]React的严格模式有什么用处?react的strictMode是一个突出显示应用程序中潜在问题的工具,与Fragment一样,strictMode不会渲染任何的可见UI,它为其后代元素触发额外的检查和警告。注意:严格模式仅在开发模... 查看详情
javascript严格模式详解
...行模式,ECMAscript5添加了第二种运行模式:"严格模式"(strictmode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。设立"严格模式"的目的,主要有以下几个: -消除Javascript语法的一些不合理、不严谨之处,减少一... 查看详情
javascript严格模式详解
...行模式,ECMAscript5添加了第二种运行模式:"严格模式"(strictmode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。设立"严格模式"的目的,主要有以下几个: -消除Javascript语法的一些不合理、不严谨之处,减少一... 查看详情
javascript严格模式详解
...行模式,ECMAscript5添加了第二种运行模式:"严格模式"(strictmode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。设立"严格模式"的目的,主要有以下几个: 查看详情
严格模式更改的规则是啥?
...严格模式更改的规则是啥?【英文标题】:Whataretherulesforstrictmodechanges?严格模式更改的规则是什么?【发布时间】:2015-12-1009:09:14【问题描述】:我有几个NodeJS模块,有些使用strictmode,有些不使用。从严格模式模块调用到非严... 查看详情
(11)严格模式(usestrict)
JavaScript严格模式(strictmode)即在严格的条件下运行。严格模式下你不能使用未声明的变量。为什么使用严格模式:消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;消除代码运行的一些不安全之处,保证代码运行... 查看详情
React 中的 StrictMode 是啥?
】React中的StrictMode是啥?【英文标题】:WhatisStrictModeinreact?React中的StrictMode是什么?【发布时间】:2019-04-1012:32:34【问题描述】:我听说严格模式有助于以最佳实践方式编写React代码,它会在生命周期方法删除时发出警告。我从h... 查看详情
没有严格模式的 JSON.parse
】没有严格模式的JSON.parse【英文标题】:JSON.parsewithoutStrictMode【发布时间】:2012-03-0503:21:18【问题描述】:我正在阅读JohnResigblog关于javascript中的严格模式,但我有一个问题。StrictMode的特点之一是使用JSON.parse和JSON.stringify,但... 查看详情
react中的fragment和strictmode(代码片段)
...需要在Fragment中添加key,那么就不能使用短语法二、StrictModeStrictMode是一个用来突出显示应用程序中潜在问题的工具。与Fragment一样,StrictMode不会渲染任何可见的UI;它为其后代元素触发额外的检查和警告;严格模... 查看详情
babel 7 - 如何防止添加“严格模式”[重复]
...格模式”[重复]【英文标题】:babel7-howtopreventaddingof"strictmode"[duplicate]【发布时间】:2019-03-2013:04:05【问题描述】:我看了很多帖子,但仍然无法正常工作:(我有.babelrc"comments":false,"presets":[["@babel/env","targets":"browsers":["ios 查看详情
SyntaxError:在严格模式下使用 const
...在严格模式下使用const【英文标题】:SyntaxError:Useofconstinstrictmode【发布时间】:2014-05-0110:28:26【问题描述】:我正在使用node.js,在我的一个js文件中,我在"strictmode"中使用了const。尝试运行它时,出现错误:SyntaxError:Useofc... 查看详情
javascript优化使用严格模式(代码片段)
hive优化:严格模式
参考技术AHive提供了一个严格模式,可以防止用户执行那些可能意想不到的不好的影响查询。通过设置属性hive.mapred.mode值为默认是非严格格式nonstrict。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3钟类型... 查看详情
为啥整数上的 in_array 严格模式比非严格模式慢?
...array严格模式比非严格模式慢?【英文标题】:Whyisin_arraystrictmodeonintegersslowerthannon-strictmode?为什么整数上的in_array严格模式比非严格模式慢?【发布时间】:2019-11-1404:03:48【问题描述】:我一直认为in_array严格模式会更快或者至... 查看详情
由于严格模式,我的 React 组件渲染了两次
...染了两次【英文标题】:MyReactComponentisrenderingtwicebecauseofStrictMode【发布时间】:2020-07-2922:28:25【问题描述】:我的React组件渲染了两次。所以,我决定逐行调试,问题就在这里if(workInProgress.mode&StrictMode)instance.render();React-dom.deve... 查看详情
javascript学习4(转)
JavaScript严格模式(usestrict)JavaScript严格模式(strictmode)即在严格的条件下运行。使用"usestrict"指令"usestrict"指令在JavaScript1.8.5(ECMAScript5)中新增。它不是一条语句,但是是一个字面量表达式,在JavaScript旧版本中会被忽略。"usestrict"... 查看详情