研究glide源码时发现了下面一段代码
@Override
public synchronized Thread newThread(@NonNull Runnable runnable) {
final Thread result =
new Thread(runnable, "glide-" + name + "-thread-" + threadNum) {
@Override
public void run() {
// why PMD suppression is needed: https://github.com/pmd/pmd/issues/808
android.os.Process.setThreadPriority(
DEFAULT_PRIORITY); // NOPMD AccessorMethodGeneration
if (preventNetworkOperations) {
StrictMode.setThreadPolicy(
new ThreadPolicy.Builder().detectNetwork().penaltyDeath().build());
}
try {
super.run();
} catch (Throwable t) {
uncaughtThrowableStrategy.handle(t);
}
}
};
threadNum++;
return result;
}
}
StrictMode
StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题,如ANR.
两种侦测策略
个是线程策略,即TreadPolicy,另一个是VM策略,即VmPolicy
ThreadPolicy线程策略检测
- detectAll() : 侦测一切潜在违规
- detectCustomSlowCalls() : 侦测自定义的耗时操作
- detectDiskReads() : 侦测磁盘读
- detectDiskWrites() : 侦测磁盘写
- detectNetwork() : 侦测网络操作
- permitAll() : 禁用所有侦测
- permitDiskReads() : 允许磁盘读
VmPolicy虚拟机策略检测
- detectAll() : 侦测一切潜在违规
- detectActivityLeaks() : 侦测Activity(活动)泄露
- detectLeakedClosableObjects() : 当显式中止方法调用之后,假如可被Closeable类或其他的对象没有被关闭。
通常在Application和Activity的开始处(如onCreate)添加代码使能StrictMode,
public void onCreate() {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
super.onCreate();
}
检查StrictMode的结果
当在策略中设置penaltyLog()时,可以在系统log中打印相关log,可以使用”adb logcat -s StrictMode“进行查看。例如下面这段log,说明涉嫌违规的操作是StrickMode:DiskReadViolation,耗时48ms。
D StrictMode: StrictMode policy violation; ~duration=48 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=4390919 violation=2
at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1263)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1039)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:840)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:219)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:268)
at com.gm.android.emojistore.provider.EmojiStoreProvider.handleEtxetQuery(EmojiStoreProvider.java:108)
at android.content.ContentProvider.query(ContentProvider.java:1017)
at android.content.ContentProvider$Transport.query(ContentProvider.java:238)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
除了通过日志查看之外,我们也可以在开发者选项中开启严格模式,开启之后,如果主线程中有执行时间长的操作,屏幕则会闪烁,这是一个更加直接的方法。
BlockCanary
扫描二维码关注公众号,回复:
13257956 查看本文章
非侵入式的性能监控函数库 主要监控主线程卡顿 通过对比消息分发开始和结束时间点计算消息处理速来判断线程卡顿
LeakCanary 内存泄漏监测
参考