onAttach(Activity)已弃用:我可以在其中检查活动是否实现了回调接口

时间:2015-08-27 19:41:18

标签: android android-fragments

在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(Context context)中进行相同的检查是否安全,或者是否有更好的方法来获取持有者活动实例?

7 个答案:

答案 0 :(得分:27)

检查源代码:

cmake/

如果有主机活动,则/** * 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)

答案 1 :(得分:4)

嗯,弃用的是onAttach(Activity activity);方法,但整个流程仍然存在。所以你可能没有做任何事情,因为onAttach(Activity activity);将会得到足够长时间的支持。

答案 2 :(得分: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);
    }
}

备注

  • 由于父Activity必须实现我们的OnFragmentInteractionListener(任意命名的接口),因此检查(context instanceof OnFragmentInteractionListener)可确保上下文实际上是活动。

  • 请注意,我们正在使用支持库。否则,API 23的早期版本将不会调用onAttach(Context context)

另见

答案 3 :(得分: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进行类型转换以获取活动。这是因为Context可以传播到作为活动的子类。

另一个问题,API 23离现在还很遥远,让我们担心。如果你担心,使用build pragma(静态Build)可能是个不错的选择。

答案 4 :(得分:1)

我遇到了同样的情况。我已经经历了各种帖子,最后在片段的onCreate()块中实现了我的代码。到现在我还没有遇到任何问题,我认为它不会成为一个问题,因为在onAttach之后立即调用onCreate的生命周期。

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

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

答案 5 :(得分:1)

我使用原生Fragment而不是one from the Support Library。我在我的代码中放了两个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)方法中。

答案 6 :(得分:0)

 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);
  }
 }