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 (Ive запустите его в AS Emulator), вы увидите, что будет вызван метод onAttach (Context).
Во время процесса отображения фрагмента FragmentManager в определенный момент вызывается метод onAttach (..). Используя getFragmentManager(), вы получите экземпляр диспетчера фрагментов, доступный для версии Android, которая запущена на этом устройстве (например, API 22, 23). В случае, если приложение работает на устройстве с API < 23 метод onAttach (Контекст) недоступен, менеджер фрагментов не знает, что в API 23 существует метод onAttach (Context), поэтому поэтому он не вызывается для API < 23 → решение для подобных задач использует FragmentManager из библиотек поддержки.
Решения:
-
Использование getSupportFragmentManager() заставит вас использовать фрагмент из библиотеки поддержки. Итак, первое решение - заменить все фрагменты фрагментом из lib и использовать getSupportFragmentManager().
-
Решение, которое я уже реализовал, состоит в том, чтобы обрабатывать 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) на всех фрагментах, где мне это нужно.
Ответы
Ответ 1
Я решил проблему таким образом:
@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) {}
Ответ 2
Вам следует попробовать использовать версию библиотеки поддержки Fragment.
Вам нужно переключиться на import android.support.v4.app.Fragment;
вместо import android.app.Fragment;
. Вам также нужно убедиться, что вы используете getSupportFragmentManager()
вместо getFragmentManager()
.
Ответ 3
Я столкнулся с той же проблемой.
У меня есть 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). Спасибо за головы!
Ответ 4
просьба сообщить об этом BUG здесь
ВЫПУСК, ОТКРЫТЫЙ НА ПРОЕКТЕ GOOGLE AOSP:
https://code.google.com/p/android/issues/detail?id=185465
пс. это не ваша работа, чтобы найти решение этой проблемы и найти какие-то способы обхода... но заставить Google исправить свой сломанный API!
для этого вам нужно жаловаться, как я сказал.
связанная проблема - getContext() из фрагмента:
https://code.google.com/p/android/issues/detail?id=185848
Ответ 5
После того, как я прочитал ваш ответ @David Rauca
Я думаю, что второй может решить мою проблему. Но, когда я смотрю в исходный код. Я обнаружил, что на самом деле onAttach(Context context)
ничего не делает на Android M, просто вызвал старый метод.
В качестве решения:
@SuppressWarnings("deprecation")
Просто добавьте его в старый метод - лучшее решение.
Ответ 6
Я столкнулся с той же проблемой.
Что я сделал для его решения:
-
Измените тип аргумента onAttach callback от Activity до Контекст.
По неизвестной причине это изменение приводит к тому, что
метод onAttach (Контекст) больше не вызывается во время жизненного цикла фрагмента. Как
следствие, мое приложение рушилось, так как код, который был в onAttach
метод никогда не выполнялся.
-
Переместите код, который был в методе onAttach, в onCreate, поскольку он все еще выполняется.
С этой модификацией приложение становится функционировать по-прежнему. Никаких дополнительных инструкций import
не требуется.