【发布时间】:2017-06-21 11:20:57
【问题描述】:
LeakCanary 在我的代码中发现了泄漏
* classifieds.yalla.features.ad.page.seller.SellerAdPageFragment has leaked:
* GC ROOT android.view.inputmethod.InputMethodManager$1.this$0 (anonymous subclass of com.android.internal.view.IInputMethodClient$Stub)
* references android.view.inputmethod.InputMethodManager.mNextServedView
* references android.support.v4.widget.DrawerLayout.mContext
* references classifieds.yalla.features.host.HostActivity.fragNavController
* references com.ncapdevi.fragnav.FragNavController.mFragmentManager
* references android.support.v4.app.FragmentManagerImpl.mCreatedMenus
* references java.util.ArrayList.elementData
* references array java.lang.Object[].[0]
* leaks classifieds.yalla.features.ad.page.seller.SellerAdPageFragment instance
但是当我查看FragmentManagerImpl
FragmentManagerImpl.mCreatedMenus 被清除时我没有发现。我发现的唯一代码是添加新片段时。不应该以某种方式管理吗?
public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
boolean show = false;
ArrayList<Fragment> newMenus = null;
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
if (f != null) {
if (f.performCreateOptionsMenu(menu, inflater)) {
show = true;
if (newMenus == null) {
newMenus = new ArrayList<Fragment>();
}
newMenus.add(f);
}
}
}
}
if (mCreatedMenus != null) {
for (int i=0; i<mCreatedMenus.size(); i++) {
Fragment f = mCreatedMenus.get(i);
if (newMenus == null || !newMenus.contains(f)) {
f.onDestroyOptionsMenu();
}
}
}
mCreatedMenus = newMenus;
return show;
}
【问题讨论】:
-
你能发帖
SellerAdPageFragment吗? -
@azizbekian 它很大。我的观点是,当片段删除时 mCreatedMenus 没有被清除,它在使用菜单创建新片段时重新分配,然后 mCreatedMenus 中的旧片段将被释放
-
那是因为您以某种方式保留了对片段的引用。
-
fragmentManager 在此字段中保留引用
ArrayList<Fragment> mCreatedMenus; -
我理解你的观点和 FragmentManagerImpl 中的代码;但是如何确保 mCreatedMenus 导致了内存泄漏?您还看到其他日志吗?
标签: android android-fragments android-support-library leakcanary