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
}