问题遇到的现象和发生背景
你好 兄弟, 我封装了一个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);
可惜检测结果依然会报相同的错误,麻烦兄弟看看有没有好的解决办法.
我想要达到的结果
有没有好的办法解决内训泄漏