You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MobileAds.registerWebView引发Activity内存泄漏问题及解决方案咨询

解决MobileAds.registerWebView导致的Activity内存泄漏问题

问题描述

在Activity的onCreate方法中调用MobileAds.registerWebView(webView)后,LeakCanary检测到内存泄漏;移除该代码后泄漏提示消失。泄漏链如下(已翻译为中文):

GC根节点: Thread对象
│
├─ Dk实例
│    是否泄漏: 否 (PathClassLoader↓ 未泄漏)
│    线程名称: 'CleanupReference'
│    ↓ Thread.contextClassLoader
├─ dalvik.system.PathClassLoader实例
│    是否泄漏: 否 (zzbzz↓ 未泄漏,且类加载器永远不会泄漏)
│    ↓ ClassLoader.runtimeInternalObjects
├─ java.lang.Object[] 数组
│    是否泄漏: 否 (zzbzz↓ 未泄漏)
│    ↓ Object[2266]
├─ com.google.android.gms.internal.ads.zzbzz 类
│    是否泄漏: 否 (类永远不会泄漏)
│    ↓ static zzbzz.zza
│                   ~~~
├─ com.google.android.gms.internal.ads.zzcfk实例
│    是否泄漏: 未知
│    保留16 B在1个对象中
│    ↓ zzasd.zza
│            ~~~
├─ com.google.android.gms.ads.nonagon.signalgeneration.ab实例
│    是否泄漏: 未知
│    保留379.4 kB在5156个对象中
│    e是sg.just4fun.tgasdk.ui.HomeActivity的实例,且mDestroyed = true
│    ↓ ab.e
│         ~
╰→ xxx.xxx.WebViewActivity实例
​     是否泄漏: 是 (ObjectWatcher监控到该对象,因为xxx.xxx.WebViewActivity已收到Activity#onDestroy()回调,且
​     Activity#mDestroyed为true)
​     保留376.6 kB在5078个对象中
​     key = 9500b00e-35f4-476d-bb2e-836c21f4c80f
​     watchDurationMillis = 7971
​     retainedDurationMillis = 2971
​     mApplication是com.just4fun.tga.App的实例
​     mBase是androidx.appcompat.view.ContextThemeWrapper的实例

泄漏原因分析

从泄漏链可以看出,广告SDK的静态引用(zzbzz.zza)最终持有了已销毁的WebViewActivity实例,导致GC无法回收该Activity。核心原因是MobileAds.registerWebView会让SDK持有WebView的强引用,而WebView又关联着Activity的上下文,Activity销毁后SDK未及时释放这些引用。

解决方案

1. 升级Google Ads SDK到最新版本

旧版本SDK存在的内存泄漏问题通常会在新版本中修复。打开项目的build.gradle文件,将play-services-ads依赖更新到最新稳定版:

dependencies {
    implementation 'com.google.android.gms:play-services-ads:22.6.0' // 替换为当前最新版本
}

2. 在Activity销毁时完整清理WebView资源

在WebViewActivity的onDestroy方法中,按顺序执行以下操作,确保释放所有关联引用:

@Override
protected void onDestroy() {
    if (webView != null) {
        // 先从父布局移除WebView,避免父容器持有引用
        ViewParent parent = webView.getParent();
        if (parent != null) {
            ((ViewGroup) parent).removeView(webView);
        }
        
        // 停止加载并清理WebView内部资源
        webView.stopLoading();
        webView.getSettings().setJavaScriptEnabled(false);
        webView.clearHistory();
        webView.clearCache(true);
        webView.removeAllViews();
        
        // 销毁WebView并置空引用
        webView.destroy();
        webView = null;
    }
    
    super.onDestroy();
}

3. 尝试用Application Context初始化WebView(可选)

如果上述步骤仍无法解决泄漏,可以尝试用Application Context创建WebView,避免WebView持有Activity的强引用:

webView = new WebView(getApplicationContext());
// 后续添加到布局的逻辑保持不变

注意:这种方式可能导致部分WebView功能异常(如弹窗、权限请求),需要测试验证后再使用。

4. 验证泄漏修复结果

重新运行App,触发Activity销毁流程,通过LeakCanary再次检测,确认内存泄漏是否消失。


内容的提问来源于stack exchange,提问作者user3610389

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:50:18