it-swarm.com.ru

Android Фрагмент 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.

309
TareK Khoury

Активность - это контекст, поэтому, если вы можете просто проверить, что контекст - это Активность, и при необходимости разыграть его.

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity a;

    if (context instanceof Activity){
        a=(Activity) context;
    }

}

Обновление: Некоторые утверждают, что новое переопределение Context никогда не вызывается. Я провел несколько тестов и не могу найти сценарий, где это правда, и в соответствии с исходным кодом, это никогда не должно быть правдой. Во всех случаях, которые я тестировал, вызывались как до, так и после SDK23 версии Activity и Context версии onAttach. Если вы можете найти сценарий, в котором это не так, я бы предложил вам создать пример проекта, иллюстрирующий проблему, и сообщить об этом команде Android .

Обновление 2: Я всегда использую только фрагменты библиотеки поддержки Android, поскольку ошибки там исправляются быстрее. Кажется, вышеупомянутая проблема, где переопределения не вызываются правильно, выявляется, только если вы используете фрагменты каркаса.

320
Kuffs

Это еще одно отличное изменение от 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
    }
}
43
Yoann Hercouet

Если вы используете фрагменты фреймворка и SDK-версия устройства ниже 23, OnAttach(Context context) не будет вызываться.

Вместо этого я использую вспомогательные фрагменты, поэтому устаревание исправлено, и всегда вызывается onAttach(Context context).

38
kikermo

В настоящее время из кода фрагмента onAttach неясно, является ли текущее действие 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

10
royB
@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity activity = context instanceof Activity ? (Activity) context : null;
}
6
worked

Хотя кажется, что в большинстве случаев достаточно иметь функцию 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
}
3
Gavriel

Загрузите новейшую библиотеку поддержки с менеджером SDK и включите

compile 'com.Android.support:appcompat-v7:23.1.1'

в gradle.app и установите версию компиляции на API 23

3
Essah

вы, вероятно, используете Android.support.v4.app.Fragment. Для этого вместо метода onAttach просто используйте getActivity(), чтобы получить FragmentActivity, с которым связан фрагмент. В противном случае вы можете использовать метод onAttach(Context context).

1
LeoCoder

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

Я использовал этот код на уроке, и он сработал.

public void onAttach(Context context){
    super.onAttach(context);

    Activity activity = getActivity();

Я волновался, что активность может быть нулевой, как указано в документации.

getActivity

FragmentActivity getActivity () Возвращает FragmentActivity, с которым в данный момент связан этот фрагмент. Может возвратить нуль, если вместо этого фрагмент связан с Контекстом.

Но onCreate для main_activity ясно показывает, что фрагмент был загружен, и поэтому после этого метода вызов действия get из фрагмента вернет класс main_activity.

getSupportFragmentManager (). beginTransaction () .add (R.id.fragment_container, firstFragment) .commit ();

Я надеюсь, что я прав с этим. Я абсолютный новичок.

1
Roy Selim