前言:
StrictMode,严格模式,算是比较简单的性能检测方法。简单介绍,技术小黑屋写的很详细。
1. StrictMode概念:
StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them.
StrictMode是一个开发者工具,检测你可能由于疏忽而犯的性能问题,并主动提示你修改它。
2. 开启StrictMode
使用代码在Application中开启:
通过配置可以在logcat中查看,也可以弹出dialog、闪烁屏幕等。当然也可以通过通过开发者模式开启。
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll() //全都检测
.penaltyFlashScreen() // Flash the screen during a violation.
.penaltyDialog() // Show an annoying dialog to the developer on detected violations
.penaltyLog()
//.detectDiskReads()
//.detectDiskWrites()
//.detectNetwork()
//.detectCustomSlowCalls()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
//.detectLeakedSqlLiteObjects()
//.detectLeakedClosableObjects()
//.detectActivityLeaks()
//.penaltyDeath() //Crashes the whole process on violation,一旦发现问题崩溃进程
.build());
}
super.onCreate();
}
3. 查看Log
当log太多是,则可通过adb命令: adb logcat | grep StrictMode
直接抓取特定log查看。
4. 扯扯源码
看了下源码,貌似主要是AndroidBlockGuardPolicy
类在做监控。
这个类毕竟是对整个App做全局监控,按照技术小黑屋的分析,在所有这些地方,都使用BlockGuard
进行回调,传给StrictMode去检测处理。这样设计也挺好,不需使用代理、反射等,也不错。
@Override
public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
BlockGuard.getThreadPolicy().onReadFromDisk();
if ((mode & O_ACCMODE) != O_RDONLY) {
BlockGuard.getThreadPolicy().onWriteToDisk();
}
return os.open(path, flags, mode);
}
那么接下就是onWriteToDisk()
:
// Part of BlockGuard.Policy interface:
public void onWriteToDisk() {
if ((mPolicyMask & DETECT_DISK_WRITE) == 0) {
return;
}
if (tooManyViolationsThisLoop()) {
return;
}
BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask);
e.fillInStackTrace();
startHandlingViolationException(e);
}
然后会走到handleViolationWithTimingAttempt()方法来,对
void handleViolationWithTimingAttempt(final ViolationInfo info) {
//...
//使用ThreadLocal<Handler>来插入Message,
threadHandler.get().postAtFrontOfQueue(new Runnable() {
public void run() {
long loopFinishTime = SystemClock.uptimeMillis();
if (windowManager != null) {
try {
windowManager.showStrictModeViolation(false);
} catch (RemoteException unused) {
}
}
for (int n = 0; n < records.size(); ++n) {
ViolationInfo v = records.get(n);
v.violationNumThisLoop = n + 1;
v.durationMillis =
(int) (loopFinishTime - v.violationUptimeMillis);
handleViolation(v);
}
records.clear();
}
});
}
然后走到handleViolation()里
void handleViolation(final ViolationInfo info) {
//主要是一些打印操作
}
结语:
StrictMode比较容易学习,使用adb命令也能很轻易的排查到问题。功能强大,SDK提供的一个好工具,应该是一个初步的优化操作。