归志宁无五亩园,读书本意在元元。这篇文章主要讲述App优化 StrictMode 严格模式相关的知识,希望能为你提供帮助。
StrictMode简介
StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例。一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例。除了主线程,我们还可以在Handler,AsyncTask,AsyncQueryHandler,IntentService等API中使用StrictMode。
示例代码
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.推荐阅读
- Android录音暂停和继续
- AndroidStudio OpenCv的配置,不用安装opencv manager
- JavaFX多重转换
- JavaFX Light.Point效果
- JavaFX Light Distant效果
- JavaFX MotionBlur效果
- JavaFX菜单
- JavaFX LineChart
- JavaFX Line