FragmentStatePagerAdapter 正在泄漏,我不知道为什么在使用 LeakCanary 时
FragmentStatePagerAdapter is leaking and I can't figure out why when using LeakCanary
我正在使用 LeakCanary 来帮助检测泄漏,但我一直遇到这种泄漏,但我不明白为什么会这样。
我有一个 FragmentStatePagerAdapter,它使用默认的屏幕外限制,即每侧加载一个。
我的 Fragment 中只有使用 Glide 加载图像。
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_viewpager_image_view, container, false);
ButterKnife.bind(this, view);
Glide.with(mContext).load(mUrl)
.apply(RequestOptions.centerInsideTransform())
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
mProgressBar.setVisibility(View.INVISIBLE);
errorImageView.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.VISIBLE);
Glide.with(mContext)
.load(R.drawable.snail)
.apply(RequestOptions.centerInsideTransform())
.into(errorImageView);
String text = "Failed to load image \n" + mUrl;
errorTextView.setText(text);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
mProgressBar.setVisibility(View.INVISIBLE);
return false;
}
})
.into(mImage);
return view;
}
LeakCanary 消息不会在我每次滚动时弹出,这令人沮丧,因为我无法确定如何重新创建错误。我可以在 LeakCanary 消息弹出窗口之前滚动并加载 30-50 张图像。
├─ e.com.app.ui.viewpager.ViewpagerImageFragment instance
│ Leaking: UNKNOWN
│ Anonymous class implementing com.bumptech.glide.request.RequestListener
│ ↓ ViewpagerImageFragment.this[=11=]
│ ~~~~~~
╰→ e.com.app.ui.viewpager.ViewpagerImageFragment instance
Leaking: YES (ObjectWatcher was watching this because e.com.app.ui.viewpager.ViewpagerImageFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = 3e232914-78d0-457c-9ca5-c6e9c8f92c55
watchDurationMillis = 7300
retainedDurationMillis = 2300
key = f745901e-5222-42db-b594-f07a47b84788
究竟是什么导致泄漏?
使用 Glide.with(this)
,其中 this
是 Fragment 实例,这样你的 Glide 请求将绑定到你的 Fragment 生命周期而不是 Activity。
我正在使用 LeakCanary 来帮助检测泄漏,但我一直遇到这种泄漏,但我不明白为什么会这样。
我有一个 FragmentStatePagerAdapter,它使用默认的屏幕外限制,即每侧加载一个。
我的 Fragment 中只有使用 Glide 加载图像。
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_viewpager_image_view, container, false);
ButterKnife.bind(this, view);
Glide.with(mContext).load(mUrl)
.apply(RequestOptions.centerInsideTransform())
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
mProgressBar.setVisibility(View.INVISIBLE);
errorImageView.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.VISIBLE);
Glide.with(mContext)
.load(R.drawable.snail)
.apply(RequestOptions.centerInsideTransform())
.into(errorImageView);
String text = "Failed to load image \n" + mUrl;
errorTextView.setText(text);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
mProgressBar.setVisibility(View.INVISIBLE);
return false;
}
})
.into(mImage);
return view;
}
LeakCanary 消息不会在我每次滚动时弹出,这令人沮丧,因为我无法确定如何重新创建错误。我可以在 LeakCanary 消息弹出窗口之前滚动并加载 30-50 张图像。
├─ e.com.app.ui.viewpager.ViewpagerImageFragment instance
│ Leaking: UNKNOWN
│ Anonymous class implementing com.bumptech.glide.request.RequestListener
│ ↓ ViewpagerImageFragment.this[=11=]
│ ~~~~~~
╰→ e.com.app.ui.viewpager.ViewpagerImageFragment instance
Leaking: YES (ObjectWatcher was watching this because e.com.app.ui.viewpager.ViewpagerImageFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = 3e232914-78d0-457c-9ca5-c6e9c8f92c55
watchDurationMillis = 7300
retainedDurationMillis = 2300
key = f745901e-5222-42db-b594-f07a47b84788
究竟是什么导致泄漏?
使用 Glide.with(this)
,其中 this
是 Fragment 实例,这样你的 Glide 请求将绑定到你的 Fragment 生命周期而不是 Activity。