Хобрук: Ваш путь к мастерству в программировании

Фрагмент - как getActivity() может вернуть null ПОСЛЕ onAttach

У меня есть класс менеджера, который является сохраненным фрагментом и содержит несохраненные фрагменты и AsyncTasks этих фрагментов.

После поворота экрана я хочу связать новые фрагменты и запущенные/завершенные задачи друг с другом и обновить фрагменты данными, предоставленными задачей.

Теперь в моем сохраненном фрагменте у меня есть следующий код:

@Override
public void onAttach(Activity activity)
{
    mFragStatePagerAdapter.update(activity.getSupportFragmentManager());
    
    Debugger.Debug(DEBUG, getClass(), "ON_ATTACH_0: parentActivity: {" + 
        (activity != null ? activity.hashCode() : "NULL") + "}");

    for (int i = 0; i < mFragStatePagerAdapter.getFragmentListSize(); i++)
    {
        Frag f = mFragStatePagerAdapter.tryGetItem(i);
        
        if (f != null)
            f.onAttach(activity);

        // alternatively I tried following as well
        // if (f != null)
        //     activity.getSupportFragmentManager().beginTransaction().attach(f).commit();
        
        Debugger.Debug(DEBUG, getClass(), "ON_ATTACH_1: this: " + 
            this.hashCode() + " fragment: " + f + ", 
            parentActivity: {"+ (f.getActivity() != null ? f.getActivity().hashCode() : "NULL") + "}");
    }
    
    
    for (int i = 0; i < mTasks.size(); i++)  
    {
        if (mTasks.get(i) != null)
        {
            Frag f = getFragment(i);
            mTasks.get(i).attach(f, mTaskCallbacks.get(i));
            if (mTasks.get(i).getStatus() == Status.FINISHED)
                mTasks.get(i).deliverResult();
        }
    }
    
    super.onAttach(activity);
}

Для объяснения:

  • Фрагмент... это класс, расширяющий Фрагмент
  • mFragStatePagerAdapter... это расширенный FragmentStatePagerAdapter с функциональностью для получения фрагментов по индексу...

Теперь моя проблема заключается в следующем (сокращенном) выводе отладки:

ON_ATTACH_0: parentActivity: {1123400376}

ON_ATTACH_1: это: фрагмент 1121944544: ExerciseViewFragment{42e2da98}, parentActivity: {NULL}

Так почему же после вызова f.onAttach(activity) f.getActivity() возвращает null? Я НЕ переопределяю onAttach в своем расширенном классе фрагментов, так что это не может быть причиной...


  • Я не думаю, что вы должны сами звонить f.onAttach(activity);. 18.07.2013
  • Я добавил альтернативу, потому что это привело меня к следующей идее: вместо этого использовать activity.getSupportFragmentManager().beginTransaction().attach(f).commit();... но, к сожалению, это тоже не сработало... так что, если onAttach не следует использовать таким образом, как я могу достичь своей цели? Фрагмент должен быть снова присоединен к новой активности... чтобы я мог обновить данные своего фрагмента... 18.07.2013
  • Что-то подозрительно в реализации вашего адаптера, потому что эти фрагменты должны иметь действительную ссылку на активность, если они в настоящее время видны в ViewPager (вызов onAttach самостоятельно, это неправильно). В любом случае, вместо того, чтобы ваш сохраненный фрагмент пытался отправить данные другим фрагментам, почему бы вам не сделать его простым держателем данных и не позволить другим фрагментам использовать его непосредственно из своей реализации. 18.07.2013
  • На самом деле, я тоже об этом думал... Теперь у меня есть сохраненный фрагмент, который содержит задачи, и фрагменты пейджера смотрят в сохраненном фрагменте, существует ли задача, и либо прикрепляются к этой задаче, либо, если она уже завершена, используйте это данные задач или создайте новый поток и добавьте его в сохраненный фрагмент... Таким образом, пока все работает... так что спасибо, что указали мне правильное направление... потратьте целый день на написание многоразового менеджера для пейджера + индикатора страницы + фрагменты, которые загружают свои данные в поток... теперь у меня есть кое-что, так что спасибо 19.07.2013

Ответы:


1

Я думаю, что ваша проблема со звонком

super.onAttach(activity);

в конце вашего метода onAttach. Назовите его первым в этом методе, например:

@Override
public void onAttach(Activity activity)
{
     super.onAttach(activity)

     // and here goes your code
     [...]
}
26.08.2015
  • Я больше не использую этот код, но помню, что это было необходимо. Мне приходилось это делать раньше. И проблема была не в том, что сохраненный фрагмент вызывал исключение, фрагменты, прикрепленные вручную (вы можете видеть это в коде), были прикреплены и СРАЗУ после этого не возвращали активность, к которой они только что были прикреплены... 26.08.2015

  • 2

    Согласно документации с https://developer.android.com/reference/android/support/v4/app/Fragment.html#getActivity()

    getActivity() может возвращать значение null, если вместо этого фрагмент связан с контекстом.

    И согласно этой документации https://developer.android.com/reference/android/support/v4/app/Fragment.html#onAttach(android.app.Activity), onAttach(Activity activity) устарел, поэтому используйте вместо него onAttach(Context).

    26.08.2015
  • это правда, но только если вы используете последние версии библиотеки поддержки. Вопрос был задан в 2013 году, и тогда он работал немного иначе :-) 26.08.2015
  • Новые материалы

    Как симулировать серию пенальти на Python с помощью симуляции Монте-Карло, часть 1: генерация функций
    Серия пенальти была огромным испытанием во время чемпионата мира по футболу. Они вызвали много споров в социальных сетях и новостных агентствах. Даже финальный матч турнира решался по..

    AST для разработчиков JavaScript
    TL; DR Эта статья - мое выступление на недавно состоявшейся конференции Stockholm ReactJS Meetup. Вы можете посмотреть слайды здесь..

    5 проектов на Python, которые нужно создать прямо сейчас!
    Добро пожаловать! Python — один из моих любимых языков программирования. Если вы новичок в этом языке, перейдите по ссылке ниже, чтобы узнать о нем больше:

    Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
    DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

    «Очень простой» эволюционный подход к обучению с подкреплением
    В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..