首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LeakCanary有回调吗?

LeakCanary有回调吗?
EN

Stack Overflow用户
提问于 2018-12-13 15:11:02
回答 2查看 302关注 0票数 1

如何获得LeakCanary日志或有关泄漏的任何类型的数据?LeakCanary是否有任何回调,我们可以用它来获取“泄漏数据”,以便在事件发生时对其进行处理?我想将数据发送到我的FireBase或其他DB。

我在文件里查了一下,但没有找到一些关于它的东西。

感谢所有

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-13 20:02:39

您需要扩展DisplayLeakService

https://github.com/square/leakcanary/wiki/Customizing-LeakCanary#uploading-to-a-server

您可以更改默认行为以将泄漏跟踪和堆转储上载到您选择的服务器。

创建您自己的AbstractAnalysisResultService。最简单的方法是在调试源中扩展DisplayLeakService:

代码语言:javascript
复制
public class LeakUploadService extends DisplayLeakService {
  @Override protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
    if (!result.leakFound || result.excludedLeak) {
      return;
    }
    if (result.leakFound) {
      uploadLeakToServer(result, leakInfo);
    }
  }

  private void uploadLeakToServer(AnalysisResult result, String leakInfo) {
    // TODO Upload result to server
  }
}

您可以用AnalysisResult.leakTraceAsFakeException()将泄漏跟踪转换为假异常,并将它们上传到崩溃报告后端。下面是使用Bugsnag的方法:

代码语言:javascript
复制
public class LeakUploadService extends DisplayLeakService {

  @Override protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
    if (!result.leakFound || result.excludedLeak) {
      return;
    }
    if (result.leakFound) {
      uploadLeakToServer(result, leakInfo);
    }
  }

  private void uploadLeakToServer(AnalysisResult result, String leakInfo) {
    Client bugsnagClient = new Client(getApplication(), "YOUR_BUGSNAG_API_KEY", false);
    bugsnagClient.setSendThreads(false);
    bugsnagClient.beforeNotify(error -> {
      // Bugsnag does smart grouping of exceptions, which we don't want for leak traces.
      // So instead we rely on the SHA-1 of the stacktrace, which has a low risk of collision.
      String stackTraceString = Logs.getStackTraceString(error.getException());
      String uniqueHash = Strings.createSHA1Hash(stackTraceString);
      error.setGroupingHash(uniqueHash);
      return true;
    });

    MetaData metadata = new MetaData();
    metadata.addToTab("LeakInfo", "LeakInfo", leakInfo);
    bugsnagClient.notifyBlocking(result.leakTraceAsFakeException(), Severity.ERROR, metadata);
  }
}

接下来,您需要在LeakCanary中指定侦听器服务类:

代码语言:javascript
复制
public class DebugExampleApplication extends ExampleApplication {
  @Override protected void installLeakCanary() {
    RefWatcher refWatcher = LeakCanary.refWatcher(this)
      .listenerServiceClass(LeakUploadService.class);
      .buildAndInstall();
  }
}

不要忘记在调试AndroidManifest.xml中注册服务:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    >
  <application android:name="com.example.DebugExampleApplication">
    <service android:name="com.example.LeakUploadService" />
  </application>
</manifest>
票数 2
EN

Stack Overflow用户

发布于 2021-10-06 19:06:22

我的解决方案有点不同(基于square:https://square.github.io/leakcanary/recipes/#uploading-to-bugsnag的示例),但想法是一样的。我们使用Sentry和Firebase通过Timber记录内存泄漏。我发现哨兵登录更方便一些,因为它显示了在内存泄漏(打开屏幕、背景/前景)之前所采取的准确步骤。

代码语言:javascript
复制
/**
 * Helper class to record leak canary memory leak traces on Timber.
 */
class LeakCanaryService : OnHeapAnalyzedListener {

    private val defaultLeakListener = DefaultOnHeapAnalyzedListener.create()

    override fun onHeapAnalyzed(heapAnalysis: HeapAnalysis) {
        // Delegate to default behavior (notification and saving result)
        defaultLeakListener.onHeapAnalyzed(heapAnalysis)

        when (heapAnalysis) {
            is HeapAnalysisSuccess -> {
                val allLeakTraces = heapAnalysis
                    .allLeaks
                    .toList()
                    .flatMap { leak ->
                        leak.leakTraces.map { leakTrace -> leak to leakTrace }
                    }

                allLeakTraces.forEach { (leak, leakTrace: LeakTrace) ->
                    val exception = MemoryLeakReportingException(leak.shortDescription)
                    Timber.e(exception, "Memory leak recorded: ${exception.message}\n$leakTrace")
                }

            }
            is HeapAnalysisFailure -> {
                // Please file any reported failure to
                // https://github.com/square/leakcanary/issues
                Timber.e(
                    heapAnalysis.exception,
                    "Memory leak analysis failed: ${heapAnalysis.exception.message}"
                )

            }
        }
    }

    class MemoryLeakReportingException(message: String) : RuntimeException(message)

}

在App类中初始化该类:

代码语言:javascript
复制
LeakCanary.config = LeakCanary.config.copy(
    onHeapAnalyzedListener = LeakCanaryService()
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53764804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档