当前标签 / ContextWrapper / 总共1篇

关于视频播放 VideoView 的一个 GC 问题

这段时间在一个项目中用到了视频和图片轮播的广告,一开始我使用了 ExoPlayer 视频播放库,结果出现了一个奇葩的问题 ANR on player release #4352,我的设备系统是 Android 5.1.1 于是我尝试工程更新到 AndroidX 将 ExoPlayer 更新到最新版本,结果还是会出问题,貌似在 Android 7.0 中这个问题得到了修复。迫于这个问题的困扰,于是我放弃了 ExoPlayer 而选择系统默认的视频播放库,结果遇到了另一个令人不爽的 bug bug 详细描述

这个问题在更高的 Android 系统中已经被修复 Fix context leak

最后变相解决 VideoView 在 Activity 中内存泄漏的方法:

创建 AudioServiceActivityLeak.java 类:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * Fixes a leak caused by AudioManager using an Activity context. 
 * Tracked at https://android-review.googlesource.com/#/c/140481/1 and
 * https://github.com/square/leakcanary/issues/205
 */
public class AudioServiceActivityLeak extends ContextWrapper {

  AudioServiceActivityLeak(Context base) {
    super(base);
  }

  public static ContextWrapper preventLeakOf(Context base) {
    return new AudioServiceActivityLeak(base);
  }

  @Override public Object getSystemService(String name) {
    if (Context.AUDIO_SERVICE.equals(name)) {
      return getApplicationContext().getSystemService(name);
    }
    return super.getSystemService(name);
  }
}

在使用 VideoView 的 Activity 中重写 attachBaseContext

1
2
3
4
5
6
public class ActivityUsingVideoView extends Activity {
  
  @Override protected void attachBaseContext(Context base) {
    super.attachBaseContext(AudioServiceActivityLeak.preventLeakOf(base));
  }
}

阅读更多