Android – onAttach (Контекст), не вызываемый API 23

Я обновил SDK до последней версии (API 23), а метод onAttach(Activity) для фрагмента устарел. Поэтому вместо использования этого метода теперь я использую onAttach(Context) но этот не вызывается во время жизненного цикла. Эта операция является экземпляром AppCompatActivity из v7, а фрагмент – экземпляром класса Fragment ( android.app.Fragment ).

Любые идеи, как заставить onAttach работать в API 23?

Решение

Я нашел несколько ответов, которые помогут вам понять и исправить эту проблему:

  • Как я уже говорил, я использую эту активность из поддержки v7 (AppCompatActivity) и фрагмента из android.app.
  • Для показа фрагментов я получаю диспетчер фрагментов, используя метод getFragmentManager для активности, поэтому диспетчер фрагментов является экземпляром FragmentManager из android.app ->, и вот проблема
  • Если вы запустите приложение на устройстве с API 23 (я запустил его в AS Emulator), вы увидите, что будет вызван метод onAttach (Context). Во время процесса отображения фрагмента FragmentManager в определенный момент вызывается метод onAttach (..). Используя getFragmentManager (), вы получите экземпляр диспетчера фрагментов, доступный для версии Android, которая запущена на этом устройстве (например, API 22, 23). В случае, если приложение работает на устройстве с API <23, метод onAttach (Context) недоступен, диспетчер фрагментов не знает, что в API 23 существует метод onAttach (Context), поэтому он не вызывается Для API <23 -> решение для подобных задач использует FragmentManager из библиотек поддержки.
  • Решения:

    1. Использование getSupportFragmentManager () заставит вас использовать фрагмент из библиотеки поддержки. Итак, первое решение – заменить все фрагменты фрагментом из lib и использовать getSupportFragmentManager ().

    2. Решение, которое я уже реализовал, состоит в том, чтобы обрабатывать 2 возможности (1. приложение работает на устройстве с API <23, приложение работает на устройстве с API> = 23).

    Вкратце, в моей реализации у меня есть базовый класс для всех фрагментов из проекта, и я добавил туда этот код:

     /* * onAttach(Context) is not called on pre API 23 versions of Android and onAttach(Activity) is deprecated * Use onAttachToContext instead */ @TargetApi(23) @Override public final void onAttach(Context context) { super.onAttach(context); onAttachToContext(context); } /* * Deprecated on API 23 * Use onAttachToContext instead */ @SuppressWarnings("deprecation") @Override public final void onAttach(Activity activity) { super.onAttach(activity); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { onAttachToContext(activity); } } /* * Called when the fragment attaches to the context */ protected void onAttachToContext(Context context) { } 

    Теперь я просто переопределяю метод onAttachToContext (Context) на всех фрагментах, где мне это нужно.

    Solutions Collecting From Web of "Android – onAttach (Контекст), не вызываемый API 23"

    Я решил проблему таким образом:

     @TargetApi(23) @Override public void onAttach(Context context) { //This method avoid to call super.onAttach(context) if I'm not using api 23 or more //if (Build.VERSION.SDK_INT >= 23) { super.onAttach(context); onAttachToContext(context); //} } /* * Deprecated on API 23 * Use onAttachToContext instead */ @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); if (Build.VERSION.SDK_INT < 23) { onAttachToContext(activity); } } /* * This method will be called from one of the two previous method */ protected void onAttachToContext(Context context) {} 

    Вы должны попробовать использовать версию библиотеки поддержки Fragment.

    Вам нужно переключиться на import android.support.v4.app.Fragment; Вместо import android.app.Fragment; , Вам также необходимо убедиться, что вы используете getSupportFragmentManager() вместо getFragmentManager() .

    Просьба сообщить об этом BUG здесь

    ВОПРОС, ОТКРЫТЫЙ НА ПРОЕКТЕ GOOGLE AOSP HOMESITE:

    https://code.google.com/p/android/issues/detail?id=185465

    пс. Это не ваша работа по поиску решения этой проблемы и найти какие-то способы обхода … но заставить Google исправить свой сломанный API! Для этого вам нужно жаловаться, как я сказал.

    Связанная с этим проблема – getContext () из фрагмента:

    https://code.google.com/p/android/issues/detail?id=185848

    Я столкнулся с той же проблемой. У меня есть minSdkVersion 19, а targetSdkVersion – 23, и я использую функцию fragmentManager в AppCompatActivity.

    onAttach(Activity activity) отмечен как устаревший, но я столкнулся с авариями приложений, когда я заменил его onAttach(Context context) .

    Поэтому вместо этого у меня теперь есть обе версии, и когда я запускаю свое приложение на API22, onAttach(Activity activity) запускается , даже если он отмечен как устаревший.

    Я не тестировал его на устройстве Android Marshmallow, но я понимаю, что он будет запускать onAttach(Context context) , игнорируя другую.

    Обновление, чтобы принять во внимание наблюдение @ skaar в комментариях ниже: теперь я могу протестировать API23 и подтвердить, что запуск на платформе 23 вызывает вызовы обоих методов (с Activity и Context). Спасибо за головы!

    Я столкнулся с той же проблемой. Что я сделал для его решения:

    1. Измените тип аргумента onAttach callback из Activity to Context . По неизвестной причине это изменение приводит к тому, что метод onAttach (Context) больше не вызывается во время жизненного цикла фрагмента. Как следствие, мое приложение терпело крах, поскольку код, который был в методе onAttach, никогда не выполнялся.

    2. Переместите код, который был в методе onAttach, в onCreate, поскольку он все еще выполняется.

    С этой модификацией приложение становится функционировать по-прежнему. Никаких дополнительных заявлений на import не требуется.

    После того, как я прочитал ваш ответ @David Rauca, я думаю, что второй может решить мою проблему. Но когда я смотрю в исходный код. Я обнаружил, что на самом деле onAttach(Context context) ничего не делает на Android M, просто вызвал старый метод.

    В качестве решения:

     @SuppressWarnings("deprecation") 

    Просто добавьте его в старый метод, это лучшее решение.