Android Fragment onAttach() устарел
Я обновил свое приложение, чтобы использовать самую последнюю библиотеку поддержки (версия 23.0.0), я обнаружил, что они не рекомендовали функцию onAttach() класса Fragment.
Вместо:
onAttach (Activity activity)
Теперь:
onAttach (Context context)
Поскольку мое приложение использует активность, прошедшую до истечения срока, возможное решение, я думаю:
@Override
public void onAttach(Context context) {
super.onAttach(context);
activity = getActivity();
}
Правильно ли это будет?
UPDATE:
Если я запускаю устройство с API ниже 23, новый onAttach() даже не вызывается. Я надеюсь, что это не то, что они намеревались сделать!
ОБНОВЛЕНИЕ 2:
Проблема устранена с последними обновлениями для SDK.
Я тестировал на своем устройстве API 22 и вызывается onAttach (Context).
Нажмите здесь, чтобы следить за сообщением об ошибке, который я открыл пару недель назад, и ответами ребята из Google.
Ответы
Ответ 1
Активность - это контекст, поэтому, если вы можете просто проверить, что контекст - это Activity, и при необходимости его приложите.
@Override
public void onAttach(Context context) {
super.onAttach(context);
Activity a;
if (context instanceof Activity){
a=(Activity) context;
}
}
Обновление: Некоторые утверждают, что новое переопределение Context
никогда не вызывается. Я сделал несколько тестов и не могу найти сценарий, где это правда, и в соответствии с исходным кодом он никогда не должен быть правдой. Во всех случаях, которые я тестировал, как pre, так и post SDK23, вызывались как версии Activity
, так и Context
onAttach
. Если вы можете найти сценарий, в котором это не так, я бы предложил вам создать образец проекта, иллюстрирующий проблему, и сообщить об этом команде Android.
Обновление 2: Я использую только фрагменты библиотеки поддержки Android, так как там быстрее исправляются ошибки. Кажется, проблема выше, когда переопределения не вызываются правильно, только появляется, если вы используете фрагменты фрейма.
Ответ 2
Если вы используете фрагменты фреймворка, а версия SDK устройства ниже 23, OnAttach(Context context)
не будет вызываться.
Вместо этого я использую фрагменты поддержки, поэтому исправление устарело и OnAttach(Context context)
всегда вызывается.
Ответ 3
Это еще одно отличное изменение от Google... Предлагаемая модификация: заменить onAttach(Activity activity)
на onAttach(Context context)
разбила мои приложения на более старых API, так как onAttach(Context context)
не будет вызываться на нативных фрагментах.
Я использую собственные фрагменты (android.app.Fragment), поэтому мне пришлось сделать следующее, чтобы он снова работал на старых API (< 23).
Вот что я сделал:
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Code here
}
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Code here
}
}
Ответ 4
В настоящее время из кода onAttach
Fragment неясно, является ли текущее действие Context
: Исходный код
public void onAttach(Context context) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onAttach(hostActivity);
}
}
Если вы посмотрите на getActivity
, вы увидите тот же вызов
/**
* Return the Activity this fragment is currently associated with.
*/
final public Activity getActivity() {
return mHost == null ? null : mHost.getActivity();
}
Итак, если вы хотите быть уверенным, что получаете активность, используйте getActivity()
(в onAttach
в Fragment
), но не забудьте проверить null
, потому что если mHost
есть null
ваша активность будет null
Ответ 5
@Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = context instanceof Activity ? (Activity) context : null;
}
Ответ 6
Загрузите новейшую библиотеку поддержки с помощью диспетчера sdk и включите
compile 'com.android.support:appcompat-v7:23.1.1'
в gradle.app и установите версию компиляции в api 23
Ответ 7
Нижеприведенный ответ связан с этим предупреждением об устаревании, которое содержится в учебном пособии по фрагментам на веб-сайте разработчика Android и не может быть связано с сообщениями выше.
Я использовал этот код на уроке урока, и это сработало.
public void onAttach(Context context){
super.onAttach(context);
Activity activity = getActivity();
Я был обеспокоен тем, что активность может быть нулевой, как указано в документации.
getActivity
FragmentActivity getActivity()
Вернуть FragmentActivity, с которым в данный момент связан этот фрагмент. Может возвращать значение null, если фрагмент связан с контекстом.
Но onCreate на main_activity ясно показывает, что фрагмент был загружен, и поэтому после этого метода вызов функции get из фрагмента вернет класс main_activity.
getSupportFragmentManager() BeginTransaction.() .add(R.id.fragment_container, firstFragment).commit();
Надеюсь, я прав. Я абсолютный новичок.
Ответ 8
вы, вероятно, используете android.support.v4.app.Fragment
. Для этого вместо метода onAttach
просто используйте getActivity()
, чтобы получить FragmentActivity
, с которым связан фрагмент. Кроме того, вы можете использовать метод onAttach(Context context)
.
Ответ 9
Хотя кажется, что в большинстве случаев достаточно иметь onAttach(Context)
, есть некоторые телефоны (например: Xiaomi Redme Note 2), где он не вызывается, поэтому он вызывает NullPointerExceptions. Поэтому, чтобы быть в безопасности, я предлагаю также оставить устаревший метод:
// onAttach(Activity) is necessary in some Xiaomi phones
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
_onAttach(activity);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
_onAttach(context);
}
private void _onAttach(Context context) {
// do your real stuff here
}