王小白-WH 2022-11-16 15:25 采纳率: 0%
浏览 50

封装Toast造成内存泄漏

问题遇到的现象和发生背景

你好 兄弟, 我封装了一个Toast的工具类,结果遇到一个内存泄漏的问题.

用代码块功能插入代码,请勿粘贴截图
private static Toast createToast(Context context, String message, int duration) {

        Toast mToast = new Toast(context);
        //自定义显示样式
        View view = LayoutInflater.from(context).inflate(R.layout.rox_cus_toast, null, false);

        mToast.setView(view);
        RoxTextView rtv = view.findViewById(R.id.tv_toast);
        float textSize = rtv.getTextSize();//文字大小
        int paddingLeft = rtv.getPaddingLeft();//左右padding距离

        rtv.setText(message);

        //设置显示位置
        mToast.setGravity(Gravity.BOTTOM, 0, DensityUtil.dp2px(BOTTOM_SHOW));

        //设置显示时长
        mToast.setDuration(duration);

        mToast.show();
        return mToast;
    }
运行结果及报错内容

下面是我使用leakcanary内存检测的结果:
Leak pattern: native global variable referencing android.widget.Toast$TN
Description: Toast.TN is held by a global variable in native code due to an IPC call to show the toast.
257951 bytes retained by leaking objects
Displaying only 1 leak trace out of 2 with the same signature
Signature: 57b73389f44769aaf18fc472c6d60be789fe3191

 GC Root: Global variable in native code

 android.widget.Toast$TN instance
│    Leaking: UNKNOWN
│    Retaining 204.1 kB in 2708 objects
│    ↓ Toast$TN.mPresenter
│               ~
 android.widget.ToastPresenter instance
│    Leaking: UNKNOWN
│    Retaining 202.2 kB in 2701 objects
│    mContext instance of com.roxmotor.basecomponentdemo.WindowActivity with mDestroyed = true
│    ↓ ToastPresenter.mContext
│                     ~
      com.roxmotor.basecomponentdemo.WindowActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com.roxmotor.basecomponentdemo.WindowActivity received
​     Activity#onDestroy() callback and Activity#mDestroyed is true)
​     Retaining 128.7 kB in 1659 objects
​     key = e7d18df1-e8bd-4df0-8c4b-b9d978984bb3
​     watchDurationMillis = 9888
​     retainedDurationMillis = 4888
​     mApplication instance of com.roxmotor.basecomponentdemo.MyApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
我的解答思路和尝试过的方法
     根据检测结果我认为内存泄漏的点就是在于Toast内部 ToastPresenter持有了context对象.这里常见的解决方案是替换为applicationContext,但是我因为项目中需要使用多分屏技术,所以只能使用activity的context.我尝试过将context变为弱引用:
    
        //弱引用代替强引用
        WeakReference<Context> mContextRef = new WeakReference<>(context);
        Context contextRef = mContextRef.get();

        Toast mToast = new Toast(contextRef);
    可惜检测结果依然会报相同的错误,麻烦兄弟看看有没有好的解决办法.
我想要达到的结果
    有没有好的办法解决内训泄漏
  • 写回答

3条回答 默认 最新

  • Plantago 2022-11-16 15:54
    关注

    你这个Context 换成全局的Application试试

    评论

报告相同问题?

问题事件

  • 创建了问题 11月16日

悬赏问题

  • ¥15 matlab数据降噪处理,提高数据的可信度,确保峰值信号的不损失?
  • ¥15 怎么看我在bios每次修改的日志
  • ¥15 python+mysql图书管理系统
  • ¥15 Questasim Error: (vcom-13)
  • ¥15 船舶旋回实验matlab
  • ¥30 SQL 数组,游标,递归覆盖原值
  • ¥15 为什么我的数据接收的那么慢呀有没有完整的 hal 库并 代码呀有的话能不能发我一份并且我用 printf 函数显示处理之后的数据,用 debug 就不能运行了呢
  • ¥20 gitlab 中文路径,无法下载
  • ¥15 用动态规划算法均分纸牌
  • ¥30 udp socket,bind 0.0.0.0 ,如何自动选取用户访问的服务器IP来回复数据