Подтвердить что ты не робот

Иногда Fragment не привязан к Activity (onCreateOptionsMenu)

Не знаю, почему, но я получаю несколько сообщений об ошибках из приложения в playstore, у которого есть сообщение:

java.lang.IllegalStateException: Fragment NewsOverViewFragment{4062e840} not attached to Activity
   at android.support.v4.app.Fragment.getResources(Fragment.java:601)
   at de.dala.simplenews.ui.NewsOverViewFragment.shouldUseMultipleColumns(NewsOverViewFragment.java:153)
   at de.dala.simplenews.ui.NewsOverViewFragment.updateMenu(NewsOverViewFragment.java:145)
   at de.dala.simplenews.ui.NewsOverViewFragment.onCreateOptionsMenu(NewsOverViewFragment.java:139)

Я уже сделал исправление и проверяю, прикреплен ли фрагмент к активности, но это просто "избегает" проблемы. По-моему, это никогда не должно происходить, чтобы получить непринятое состояние в onCreateOptionsMenu или onOptionsItemSelected.

Почему это произошло? Как возможно, чтобы фрагмент вызывал onCreateOptionsMenu/onOptionsItemSelected без привязки к активности?

Привет

код:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.news_overview_menu, menu);
    updateMenu();
    super.onCreateOptionsMenu(menu, inflater);
}

private void updateMenu(){
    boolean useMultiple = shouldUseMultipleColumns();
    ...
}

private boolean shouldUseMultipleColumns(){
    boolean useMultiple = false;

    Configuration config = getActivity().getResources().getConfiguration();
            switch (config.orientation) {
                case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsLandscape();
                    break;
                case android.content.res.Configuration.ORIENTATION_PORTRAIT:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsPortrait();
                    break;
      }

    return useMultiple;
}

Как я уже сказал, теперь проверяю, прикреплен ли фрагмент, и только затем вызывается shouldUseMultipleColumns(), который исправляет проблему, но не объясняет, почему это вызвано в первую очередь...

Edit2: My Activity

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...
    if (savedInstanceState == null) {
        if (getIntent().getDataString() != null) {
            String path = getIntent().getDataString();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            currentFragment = CategoryModifierFragment.getInstance(path);
            transaction.replace(R.id.container, currentFragment).commit();
        } else {
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            currentFragment = NewsOverViewFragment.getInstance(NewsOverViewFragment.ALL);
            transaction.replace(R.id.container, currentFragment).commit();
        }
    }
    ...
}

Это процедура присоединения. Тем не менее, можно вызвать другие фрагменты, которые всегда заменяют currentFragment, поэтому есть шанс, что мой NewsOverViewFragment НЕ подключен. Но даже если это так - почему вызов onCreateOptionsMenu?

4b9b3361

Ответ 1

Вы должны проверить isAdded() фрагмента http://developer.android.com/reference/android/app/Fragment.html#isAdded()

поэтому ваш shouldUseMultipleColumns() будет выглядеть так

private boolean shouldUseMultipleColumns(){
    if(!isAdded()) return false;
    boolean useMultiple = false;

    Configuration config = getActivity().getResources().getConfiguration();
            switch (config.orientation) {
                case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsLandscape();
                    break;
                case android.content.res.Configuration.ORIENTATION_PORTRAIT:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsPortrait();
                    break;
      }

    return useMultiple;
}