Android-фрагмент onAttach () устарел

я обновил свое приложение, чтобы использовать последнюю библиотеку поддержки (версия 23.0.0), я узнал, что они устарели функцию onAttach () класса Fragment.

вместо:

onAttach (Activity activity)

сейчас:

onAttach (Context context)

поскольку мое приложение использует действие, переданное до устаревания, возможным решением, я думаю, является:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}

Это был бы правильный способ сделать это?

обновление:

Если я запускаю устройство с API ниже 23, новый onAttach () даже не вызывается. Я надеюсь, что это не то, что они намеревались сделать!

обновление 2:

проблема была решена с последними обновлениями SDK.

Я тестировал на своем устройстве API 22, и вызывается onAttach(контекст).

клик здесь чтобы следить за отчетом об ошибке, который я открыл пару недель назад, и ответы от парней в Google.

9 ответов


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

@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, поскольку ошибки там исправляются быстрее. Кажется, вышеуказанная проблема, когда переопределения не вызываются правильно, появляется только при использовании фрагментов фреймворка.


это еще одно большое изменение от Google ... Предлагаемая модификация: replace onAttach(Activity activity) С onAttach(Context context) разбил мои приложения на старых API с onAttach(Context context) не будет вызываться на собственных фрагментах.

Я использую собственные фрагменты (android.приложение.Фрагмент), поэтому мне пришлось сделать следующее, чтобы он снова работал на старых APIs (

вот что я сделал:

@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
    }
}

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

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


в настоящее время с 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() (in onAttach в своем Fragment), но не забудьте проверить null потому что если mHost is null ваша деятельность будет null


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

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

загрузите новейшую библиотеку поддержки с помощью sdk manager и включите

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

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


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

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

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

    Activity activity = getActivity();

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

getActivity

getActivity FragmentActivity () Возвращает FragmentActivity этот фрагмент в настоящее время общаться. Может возвращать значение null, если фрагмент связан с контекстом.

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

getSupportFragmentManager ().beginTransaction() .добавить(ИД Р..fragment_container, firstFragment).commit();

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


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


хотя кажется, что в большинстве случаев достаточно иметь onAttach(Context), есть несколько телефонов (i.e: Xiaomi Redme примечание 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
}