StrictMode卡顿与泄漏检测-StrictMode原理(2)

本文详细解析了Android中的StrictMode关闭检测原理,包括CloseGuard如何进行IO关闭检测,防止资源泄漏。同时,探讨了BlockGuardOS如何检测IO卡顿,并介绍了SqliteCursor的泄漏检测机制,帮助开发者提升应用性能和稳定性。

2. StrictMode关闭检测原理

StrictMode的关闭检测其实是比较简单的,基本上就是在开启的时候埋桩,释放的时候检测桩子是否有关闭,没有关闭则检测为泄漏。

2.1 CloseGuard

这里有一个预备知识,那就是CloseGuard,它是一个StrictMode专门为了处理此类事情的类,主要包括三个函数:

  • open 开始埋桩
  • close 拆桩
  • warnIfOpen 爆炸
SystemApi(client = MODULE_LIBRARIES)
@libcore.api.IntraCoreApi
public final class CloseGuard {
   
   

    private static volatile boolean stackAndTrackingEnabled = true;

    private static volatile Reporter reporter = new DefaultReporter();

    private static volatile Tracker currentTracker = null; // Disabled by default.

    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    public static void setEnabled(boolean enabled) {
   
   
        CloseGuard.stackAndTrackingEnabled = enabled;
    }


    public static boolean isEnabled() {
   
   
        return stackAndTrackingEnabled;
    }


    @UnsupportedAppUsage(trackingBug=111170242)
    @SystemApi(client = MODULE_LIBRARIES)
    @libcore.api.IntraCoreApi
    public void open(String closer) {
   
   
        openWithCallSite(closer, null /* callsite */);
    }

		//关闭之前,
    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    @libcore.api.IntraCoreApi
    public void close() {
   
   
        Tracker tracker = currentTracker;
        if (tracker != null && closerNameOrAllocationInfo instanceof Throwable) {
   
   
            // Invoke tracker on close only if we invoked it on open. Tracker may have changed.
            tracker.close((Throwable
### 使用 StrictMode 检测主线程中的耗时操作 StrictModeAndroid 提供的一个开发工具,用于检测应用程序中的潜在问题,例如耗时操作、磁盘访问或网络请求在主线程中执行的情况。以下是关于如何使用 StrictMode 检测主线程中的耗时操作的详细说明: #### 1. 启用 StrictMode StrictMode 需要在应用的调试模式下启用,通常在 `Application` 或 `Activity` 的 `onCreate` 方法中进行配置。可以通过调用 `StrictMode.setThreadPolicy` 和 `StrictMode.setVmPolicy` 来分别设置线程策略和虚拟机策略。 ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); enableStrictMode(); } private void enableStrictMode() { if (BuildConfig.DEBUG) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .detectAll() // 检测所有可能的问题 .penaltyLog() // 将违规行为记录到 Logcat .penaltyDialog() // 在违规时显示对话框(仅适用于主线程) .build(); StrictMode.setThreadPolicy(policy); StrictMode.VmPolicy vmPolicy = new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() // 检测 SQLite 对象泄漏 .detectLeakedClosableObjects() // 检测未关闭的流或其他资源 .penaltyLog() .build(); StrictMode.setVmPolicy(vmPolicy); } } } ``` #### 2. 检测主线程中的耗时操作 通过 `StrictMode.ThreadPolicy.Builder().detectAll()`,可以检测主线程中发生的以下问题: - 网络请求[^1] - 磁盘读写操作[^1] - 耗时计算逻辑[^1] 当这些操作被检测到时,StrictMode 会将相关信息输出到 Logcat 中,并可选择性地弹出警告对话框。 #### 3. 示例:模拟耗时操作并检测 假设在主线程中执行了一个耗时任务,例如模拟一个长时间运行的计算逻辑: ```java new Thread(() -> { try { Thread.sleep(5000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } }).start(); ``` 启用 StrictMode 后,Logcat 中会显示类似以下的日志信息: ``` D/StrictMode: StrictMode policy violation; ~duration=5000 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=4 ``` #### 4. 解决问题 根据 StrictMode 输出的日志信息,开发者可以定位导致卡顿的具体代码位置,并将其移至后台线程中执行。常用的方法包括: - 使用 `AsyncTask`(已废弃,但可用于旧项目)[^1] - 使用 `HandlerThread` 或 `ExecutorService` - 使用协程(Kotlin Coroutines) ### 注意事项 - StrictMode 应仅在调试模式下启用,避免对生产环境的应用性能造成影响。 - 使用 `penaltyDialog` 时需谨慎,因为它会在主线程违规时直接弹出对话框,可能会干扰用户体验。 ```java if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectNetwork() // 检测网络操作 .detectDiskReads() // 检测磁盘读取 .detectDiskWrites() // 检测磁盘写入 .penaltyLog() .penaltyDropBox() // 将违规记录保存到 DropBox .build()); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值