简单易用的Android主线程耗时检测类 MainThreadMonitor

适用场景 debug 本地测试

文章目录

  • [代码类 MainThreadMonitor.java](#代码类 MainThreadMonitor.java)
  • [使用方式 Application的attachBaseContext](#使用方式 Application的attachBaseContext)
  • log输出示例

代码类 MainThreadMonitor.java

java 复制代码
public class MainThreadMonitor {
    private static final String TAG = "MainThreadMonitor";
    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

    public static void startMonitorMainThread(long threshold) {
        executorService.scheduleAtFixedRate(() -> {
            checkMainThreadState(threshold);
        }, 0, threshold, TimeUnit.MILLISECONDS);
    }


    private static void checkMainThreadState(long threshold) {
        AtomicBoolean exec = new AtomicBoolean(false);
        long startTime = System.currentTimeMillis();

        Handler mainHandler = new Handler(Looper.getMainLooper());
        // 预期主线程执行runnable的时候会把 exec置为true
        mainHandler.post(() -> exec.set(true));

        executorService.schedule(() -> {
            // 阈值之后发现 exec 还没有置为true,说明主线程阻塞了
            if (!exec.get()) {
                printMainThreadStackTrace(startTime);
            }
        }, threshold, TimeUnit.MILLISECONDS);
    }

    private static void printMainThreadStackTrace(long startTime) {
        StackTraceElement[] stackTrace = Looper.getMainLooper().getThread().getStackTrace();
        long consumeTime = System.currentTimeMillis() - startTime;
        Log.e(TAG, String.format("start block:(%s) ms  ====================== ", consumeTime));
        for (StackTraceElement s : stackTrace) {
            Log.d(TAG, "block: " + s);
        }
    }

}

使用方式 Application的attachBaseContext

kotlin 复制代码
class App : Application() {

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MainThreadMonitor.startMonitorMainThread(500)
    }

}

log输出示例

这里需要解释一下 start block 这行的含义,我们看到后面有一个 501ms的耗时,这里并不意味 着该方法/函数执行的时间是501ms,而是表述这500ms之内都在此方法中执行,很有可能下一个500ms还是这个堆栈信息,因此 方法实际执行时间 >= 500ms

相关推荐
松仔log1 天前
Java中级——组合和继承
android·java·开发语言
我命由我123452 天前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian2332 天前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_955759622 天前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
余衫马2 天前
2026最新版!Android Studio 极速安装与配置指南
android·ide·android studio
AFinalStone2 天前
Android 7系统异常问题排查(五)Framework层(下)—System Server崩溃
android·tombstone·系统异常
AFinalStone2 天前
Android 7系统异常问题排查(八)系统追踪—Trace机制与性能诊断
android·系统异常
极客猴子2 天前
Android录音转写频繁卡顿?多款APP长时间会议场景稳定性实测
android·人工智能·智能手机·飞书
Kapaseker2 天前
Boolean 变量到底该怎么命名?
android·kotlin
AFinalStone2 天前
Android 7系统异常问题排查(六)应用异常(上)—ANR机制全解
android·系统异常