У меня есть Activity с контейнером фрагментов. В зависимости от того, какой фрагмент в данный момент находится в контейнере, мне нужно динамически менять меню ActionBar'а и передать события этого меню текущему фрагменту. Для этого, я вызываю
invalidateOptionsMenu() чтобы добиться вызова
onCreateOptionsMenu() и выставляю соответствующие слушатели:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.clear(); // Пытаюсь очистить существующим методом
Fragment fragment = getSupportFragmentManager().findFragmentByTag(mCurrentFragmentTag);
if (fragment instanceof PlayersView) {
final PlayersView view = (PlayersView) fragment;
getMenuInflater().inflate(R.menu.menu_main_players, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
view.loadData(false);
return false;
}
});
return true;
}
return super.onCreateOptionsMenu(menu);
}
И всё работает неплохо, вот только проблема возникает, когда я переключаю фрагменты. Из-за этих Listener'ов происходит утечка фрагмента, которую отлавливает
LeakCanary:
SearchView должен был быть выкинут и уничтожен сборщиком мусора, но вместо этого он находится в памяти и удерживает ссылку на фрагмент из-за Listener'а. Как избавиться от всех ссылок и избежать утечек памяти? По идее,
Menu.clear() должен это делать, но на деле толку от метода ноль. Может можно как-то полностью пересоздать объект Menu, вместо переиспользования одной инстанции?