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

封装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 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并