工具 严格模式

Tool: Strict Mode

[TOC]

背景

当你的应用中的事件处理超过了 5 秒钟没有响应的时候,Android 会弹出一个 ANR 弹窗. 这是因为 UI 线程被阻塞了,它在等待某些事情的完成.因为 UI 线程是唯一一个可以处理输入和绘制的线程,当它停止响应的时候,你的 app 也停止了响应.

那么什么会导致 UI 线程像这样停止呢?通常情况下系统调用可以无期限的阻塞它,就像磁盘或者网络获取.这些阻塞调用是你应用中的定时炸弹.在正常情况下,它们运行的非常快,你甚至无法注意到他们.但在某些软件和硬件条件以及一些运气的情况下,他们爆炸了.

方案

接下来我们来介绍一下如何找到这些隐藏的问题.这个工具的名字叫 Strict Mode ,你可以在 开发者模式中勾选上 Strict Mode Enabled 来启动它.当它是启动的时候,在你的应用中如果有在 UI 线程中的耗时操作的时候屏幕的边框会变成红色的.

Strict Mode 实际上定义了你在什么线程中可以做什么事,它有点像一个运行时的 Lint . 它是对你的线程策略做了一个规定,策略是由两个部分呢组成的

  • 检测 : 用来检测某些操作,如网络请求等
  • 处罚 : 当检测到符合条件的行为的时候的响应,如前面的红框,或者记录 log,甚至崩溃.

我们也可以使用 Strict mode 来响应一些自定义的条件.比如: 当你要监听自定义的方法的时候,在方法的开始调用 StrictMode.noteSlowCall(); 确保你在 UI 线程的策略中启用了 detectCustomSlowCalls . 这时候调用noteSlowCall 将会导致一个异常,然后策略会触发你为该线程设置的 处罚. 如果禁用了 detectCustomSlowCalls 的话 , noteSlowCall 将会是一个空调用.

1
2
3
4
5
6
7
StrictMode.noteSlowCall();
StrictMode.setThreadPolicy(
new StrictMode.ThreadPolicy.Builder()
.detectCustomSlowCalls()
.penaltyFlashScreen()
.build());

这里有一个窍门,无论何时你要获取一个锁的时候调用 noteSlowCall .

这是为什么呢? 锁是一个隐式的阻塞调用.它们通常立马就返回了,快到你甚至没有注意到它们在那.但是当他被别人获取的时候,你的线程将会被阻塞,而且没人知道它什么时候可以恢复运行.锁通常不会知道导致 ANR , 但是如果你在 UI 线程中获取锁的话,马上或者以后你将会出现丢帧的情况.

Strict Mode 同时也有给虚拟机设置策略的 API .这就是 VM 策略. VM 策略给了你一个检测内存泄露的方式.要记得,如果你缺少内存的话那么即使是一个小的分配操作也会导致几百毫秒的停顿.

Resource

https://www.youtube.com/watch?v=oGrXdxpWgyY&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=48

About Me

我的博客 leonchen1024.com

我的 GitHub https://github.com/LeonChen1024

微信公众号

wechat

You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×