android 方法卡顿检测

本文介绍了一种通过自定义BlockDetector和BlockMonitor类监测Android应用主线程卡顿的方法。利用Loop.java的loop()方法,通过替换setMessageLogging()方法中的Printer类,记录下每个消息分发与处理的起止时间,进而定位造成卡顿的具体方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、使用
1.定义两个类:BlockDetector.java、LogMonitor.java。
2.在Application中执行初始化方法。

二、原理
1.主线程所有的操作都是通过handler来执行的,所以只要监测每个msg执行的时间,就能定位出哪个方法造成卡顿。
2.在Loop.java的loop()方法中,每次执行msg.target.dispatchMessage(msg)前后都会分别打印以“>>>>> Dispatching”为前缀和“<<<<< Finished”为后缀的信息,只要通过setMessageLogging()替换Loop.java中的Printer类,就可以检测到处理每个msg的开始和结束时间。

public class BlockDetector {

    public static void init() {
        Looper.getMainLooper().setMessageLogging(new Printer() {
            //分发和处理消息开始前的log
            private static final String START = ">>>>> Dispatching";
            //分发和处理消息结束后的log
            private static final String END = "<<<<< Finished";

            @Override
            public void println(String x) {
                if (x.startsWith(START)) {
                    //开始计时
                    BlockMonitor.getInstance().startMonitor();
                }
                if (x.startsWith(END)) {
                    //结束计时
                    BlockMonitor.getInstance().removeMonitor();
                }
            }
        });
    }
}
public class BlockMonitor {
    private static final String TAG = "=====BlockMonitor=====";
    private static BlockMonitor sInstance = new BlockMonitor();
    private Handler mIoHandler;
    //方法耗时的卡口,500毫秒
    private static final long TIME_BLOCK = 500L;
    //存放一个msg周期的卡顿堆栈信息,防止重复打印
    private Set<String> mBlockStackTrace;

    private BlockMonitor() {
        HandlerThread logThread = new HandlerThread("BlockMonitor");
        logThread.start();
        mIoHandler = new Handler(logThread.getLooper());
        mBlockStackTrace = Collections.synchronizedSet(new HashSet<String>());
    }

    private Runnable mLogRunnable = new Runnable() {
        @Override
        public void run() {
            //继续检测
            startMonitor();
            //打印出执行的耗时方法的栈消息
            StackTraceElement[] stackTrace = Looper.getMainLooper().getThread().getStackTrace();
            StringBuilder sb = new StringBuilder();
            for (StackTraceElement s : stackTrace) {
                sb.append(s.toString());
                sb.append("\n");
            }
            String s = sb.toString();
            if (!mBlockStackTrace.contains(s)) {
                mBlockStackTrace.add(s);
                Log.e(TAG, s);
            }
        }
    };

    public static BlockMonitor getInstance() {
        return sInstance;
    }

    /**
     * 开始计时
     */
    public void startMonitor() {
        mIoHandler.postDelayed(mLogRunnable, TIME_BLOCK);
    }

    /**
     * 停止计时
     */
    public void removeMonitor() {
        mIoHandler.removeCallbacks(mLogRunnable);
        mBlockStackTrace.clear();
    }
}
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        BlockDetector.init();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值