• 注册
  • Android博客 Android博客 关注:0 内容:1125

    单例中使用Context内存泄漏问题

  • 查看作者
  • 打赏作者
  • 当前位置: 职业司 > Android开发 > Android博客 > 正文
    • Android博客
    • 单例中使用Context内存泄漏问题

      简介: 在单例中但凡声明Context context,开发工具都会提示Do not place Android context classes in static fields (static reference to Single which has field mContext pointing to Context); this is a memory leak (and also breaks Instant Run)

      意思是说可能存在内存泄漏。因为在单例中使用的静态类,是伴随着app的生命周期的,所以在此处使用Context context 会导致context无法被顺利回收。

      一、原始代码

      public class Single {
          private Context mContext;
          private static Single instance = null; //此处提示内存泄漏
          public static synchronized Single getInstance() {
              synchronized (Single.class) {
                  if (instance == null) {
                      instance = new Single();
                  }
              }
              return instance;
          }
          public void init(Context context) {
              mContext = context;
          }
          public void getScreenWidth() {
              ScreenUtils.getScreenWidth(mContext);
          }
          
      }
      复制代码

      二、解决办法

      方法一

      将context换成context.getApplicationContext(),此时还会提示有内存泄漏,很多开发者反馈是androidStudio的bug,如果不想有这个提示,需要忽略警告,对变量添加@SuppressLint("StaticFieldLeak")

      完整代码如下

      public class Single {
          private Context mContext;
          @SuppressLint("StaticFieldLeak") //忽略警告
          private static Single instance = null; //此处提示内存泄漏
          public static synchronized Single getInstance() {
              synchronized (Single.class) {
                  if (instance == null) {
                      instance = new Single();
                  }
              }
              return instance;
          }
          public void init(Context context) {
              mContext = context.getApplicationContext();//将`context`换成`context.getApplicationContext()`
          }
          public void getScreenWidth() {
              ScreenUtils.getScreenWidth(mContext);
          }
      }
      复制代码

      方法二

      不临时保存Context,在需要使用场景下,直接传入该方法。
      代码如下

      public class Single {
          private static Single instance = null; //此处提示内存泄漏
          public static synchronized Single getInstance() {
              synchronized (Single.class) {
                  if (instance == null) {
                      instance = new Single();
                  }
              }
              return instance;
          }
          public void getScreenWidth(Context context) { //直接引用传入的context
              ScreenUtils.getScreenWidth(context);
          }
      }
      复制代码

      我自己使用的是第二种方法,并且加上了

      context.getApplicationContext()
      复制代码

      当然,你需要了解,context与applicationContext的区别,以及你项目中场景如何应用。

      单例中使用Context内存泄漏问题

      三、参考链接

      stackoverflow.com/questions/3…
      stackoverflow.com/questions/3…

      请登录之后再进行评论

      登录

      手机阅读天地(APP)

      • 微信公众号
      • 微信小程序
      • 安卓APP
      手机浏览,惊喜多多
      匿名树洞,说我想说!
      问答悬赏,VIP可见!
      密码可见,回复可见!
      即时聊天、群聊互动!
      宠物孵化,赠送礼物!
      动态像框,专属头衔!
      挑战/抽奖,金币送不停!
      赶紧体会下,不会让你失望!
    • 实时动态
    • 签到
    • 做任务
    • 发表内容
    • 偏好设置
    • 到底部
    • 帖子间隔 侧栏位置:
    • 还没有账号?点这里立即注册