Подтвердить что ты не робот

OnAttach (Activity) устарел: где я могу проверить, реализует ли эта функция интерфейс обратного вызова

До API 23 я использовал методы Fragment onAttach для получения моего экземпляра слушателя, затем ссылка очищается внутри onDetach. например:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    mListener = null;
    try {
        mListener = (SellFragmentListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement SellFragmentListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

Безопасно ли выполнять одну и ту же проверку внутри onAttach (контекст контекста) или есть лучший способ получить экземпляр активности владельца?

4b9b3361

Ответ 1

Проверьте исходный код:

/**
 * Called when a fragment is first attached to its context.
 * {@link #onCreate(Bundle)} will be called after this.
 */
public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

/**
 * @deprecated Use {@link #onAttach(Context)} instead.
 */
@Deprecated
public void onAttach(Activity activity) {
    mCalled = true;
}

Итак, onAttach(Activity activity) вызывается onAttach(Context context), если есть активность хоста. Вы можете безопасно использовать onAttach(Activity activity).

Ответ 2

Ну, то, что устарело, - это метод onAttach(Activity activity);, но весь поток остается. поэтому вы можете ничего не делать, поскольку onAttach(Activity activity); будет поддерживаться достаточно долго.

Ответ 3

Мне никогда не приходилось использовать onAttach(Context context), но я думаю, что ваш код в основном хорош. Итак, вот мое предложение, используя ваш код:

public void onAttach (Context context) {
   super.onAttach(context);
   try {
        Activity activity = (Activity) context;
        mListener = (SellFragmentListener) activity;
   } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement SellFragmentListener");
    }
}

Основное отличие состоит в том, что я могу придать тип context для получения Activity. Это связано с тем, что Контекст может распространяться в подкласс, который является активностью.

Еще одна проблема, API 23 все еще далека от нас, чтобы мы могли волноваться. Если вы беспокоитесь, использование build pragma (static Build) может быть хорошим вариантом.

Ответ 4

Как показано в ответе Zsolt Mester, onAttach(Activity activity) устарел в пользу onAttach(Context context). Таким образом, все, что вам нужно сделать, это проверить, чтобы контекст был активным.

В Android Studio, если вы перейдете к Файл > Создать > Фрагмент, вы можете получить автоматически сгенерированный код, который будет содержать правильный синтаксис.

import android.support.v4.app.Fragment;
...

public class MyFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // inflate fragment layout
        return inflater.inflate(R.layout.fragment_myfragment, container, false);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

Примечания

  • Поскольку родительская активность должна реализовать наш OnFragmentInteractionListener (интерфейс с произвольным именем), проверка (context instanceof OnFragmentInteractionListener) гарантирует, что контекст является фактически активностью.

  • Обратите внимание, что мы используем библиотеку поддержки. В противном случае onAttach(Context context) не будет вызываться в версиях Android до версии API 23.

См. также

Ответ 5

Я столкнулся с такой же ситуацией. Я прошел через различные должности и, наконец, реализовал свой код в блоке onCreate() фрагмента. До сих пор я не сталкивался с какой-либо проблемой, и я думаю, что это не будет проблемой, поскольку onCreate вызывается сразу после onAttach в жизненном цикле.

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            listnener = (TilesOnClickListnener)getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException(getActivity().toString() + " must implement OnArticleSelectedListener");
        }
    }

Ответ 6

 public class MainActivity extends AppCompatActivity implements  topsection.TopSectionListener {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
 }



 public void createMeme(String top, String bottom){
    bottomsection fragmentbottom = (bottomsection) getSupportFragmentManager().findFragmentById(R.id.fragment2);
    fragmentbottom.setMemeText(top, bottom);
  }
 }

Ответ 7

Я использую собственный Fragment, а не one из Библиотеки поддержки. Я поместил оба метода onAttach() в свой код и проделал некоторую отладку на устройствах с разными версиями SDK. Я обнаружил, что:

SDK 22 и ниже - вызывается только onAttach(Activity). Не удивительно, потому что onAttach(Context) был введен только в SDK 23.

SDK 23 и выше - onAttach(Context) вызывается первым, а затем onAttach(Activity). (Это согласуется с тем, что @Zsolt Mester сказал об исходном коде в другом ответе на этот пост.)

Так как minSdkVersion для моего приложения было ниже 23, я просто решил полностью опустить onAttach(Context) и просто добавить аннотацию @SuppressWarnings("deprecation") к существующему методу onAttach(Activity).