【发布时间】:2018-11-12 12:05:39
【问题描述】:
我几天来一直试图找到 ActionMode 内存泄漏的来源,但没有运气。我有一个包含多个片段的活动,当我离开具有 ActionMode 的片段(同时自动取消它)时,LeakCanary 检测到内存泄漏。
我已经在destroy() 上取消了ActionMode 和ActionMode.Callback,甚至尝试在onDestroyActionMode() 上这样做。
这是我的 LeakCanary 截图:
https://i.imgur.com/RUbdqj3.png
我希望有人指出我正确的方向。
附:我怀疑它与 ActionMode.Callback 有关。虽然,我找不到任何破坏它的回调方法。我使用 startSupportActionMode(mActionModeCallback) 启动 ActionMode。我也试图找到一种方法来从中删除 mActionModeCallback,但没有方法。
这是我完整的 ActionMode 代码:
private ActionMode mActionMode;
private ActionMode.Callback mActionModeCallback;
public void startCAB()
{
if (mActionMode == null)
mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(mActionModeCallback);
}
private void buildActionModeCallBack()
{
mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_cab, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
... Some Code ...
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
mActionModeCallback = null; // Tried with and without this.
}
};
}
public void finishActionMode()
{
mActionMode.finish();
}
@Override
public void onDestroy()
{
super.onDestroy();
mActionMode = null;
mActionModeCallback = null;
}
包含片段的父 Activity:
@Override
public void onTabUnselected(TabLayout.Tab tab)
{
clearCAB();
}
private void clearCAB()
{
int index = mPagerAdapter.getCurrentFragmentIndex();
FragmentOne fragmentOne = (FragmentOne) mPagerAdapter.instantiateItem(mViewPager, index);
fragmentOne.finishActionMode();
}
【问题讨论】:
-
您是否尝试过调用
mActionMode.finish()而不是将引用显式设置为null? -
是的,我已经从我的父活动中添加了代码,它显示了我在滑动时完成 CAB 的位置。
-
在我的应用程序中遇到了同样的问题,该应用程序使用片段内的列表视图,托管在视图寻呼机中。
-
没有看到这个问题,我正在查看源代码,因为它看起来很可疑,我无法取消设置
ActionMode.Callback。一旦你调用AppCompatActivity.startSupportActionMode(mActionModeCallback),ActionMode.Callback就永远不会在你调用ActionMode.finish后被取消引用,因此回调总是有一个强引用。一种解决方案是制作一个与应用程序具有相同生命周期的回调具体实现,然后自己在自定义回调实现中设置/取消设置变量,这样谁的片段就不会泄露 - 这是一个aosp错误。 -
在这篇文章发布一年半之后,我确实遇到了这个问题。你找到解决办法了吗?