使用getActivity()进行强制转换是否安全?

时间:2014-07-19 19:46:36

标签: android android-fragments

我正在编写一个包含父Activity和多个孩子Fragments的应用。我试图让Fragment与父Activity进行通信。我知道有几种方法可以做到这一点,包括创建一个接口并在父Activity中实现它。但是,我对这种方法感兴趣:

ParentActivity activity = (ParentActivity) getActivity();
activity.someMethod();

这种方法占用的代码更少,而且复杂度更低。但是,在生产代码中这样做是否安全?或者界面更安全?

7 个答案:

答案 0 :(得分:10)

你可以使用它 -

private ParentActivity callback;

@Override
public void onAttach(Activity activity)
{
    //callback = (ParentActivity ) activity;
    // make sure there is no cast exception
    callback = (ParentActivty.class.isAssignableFrom(activity
            .getClass())) ? (ParentActivity) activity : null;

    super.onAttach(activity);
}

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

现在当你进行任何方法调用时,请像这样调用它 -

if(callback!=null)
{
callback.someMethod();
}

这种方法很安全。

答案 1 :(得分:5)

这是安全的(即你不会得到ClassCastException),只要你确保 ParentActivity创建/添加你的片段。

这些类现在有效coupled,一般 ,这不是一件好事。

答案 2 :(得分:1)

通过强制转换为特定的Activity类(ParentActivity),您将无法使用不同的活动重用该片段。只要您只使用具有该活动的片段,就可以安全地进行投射。

使用接口允许片段与多个活动一起使用 - 您只需要在使用该片段的活动中实现该接口。

另一种选择是使用事件总线 - 例如GreenRobot's EventBusSquare's Otto

答案 3 :(得分:1)

直接from the Android documentation

  

要允许Fragment与其Activity进行通信,您可以在Fragment类中定义接口并在Activity中实现它。 Fragment在其onAttach()生命周期方法中捕获接口实现,然后可以调用Interface方法以与Activity通信。

以下是片段到活动通信的示例:

// HeadlinesFragment.java
public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    public void setOnHeadlineSelectedListener(Activity activity) {
        mCallback = activity;
    }

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }

    // ...
}


// MainActivity.java
public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    // ...

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof HeadlinesFragment) {
            HeadlinesFragment headlinesFragment = (HeadlinesFragment) fragment;
            headlinesFragment.setOnHeadlineSelectedListener(this);
        }
    }
}

答案 4 :(得分:0)

我猜ParentActivity来自Activity

getActivity()将为您提供指向父活动的指针。所以,演员阵容没有问题。

做事并不是“Android方式”,但无论如何,谷歌都没有做很多“Android方式”的事情,这个演员阵容肯定会在未来的Android版本中继续运行。

答案 5 :(得分:0)

正如你自己说的,这不是一个好方法,谷歌自己的文档建议使用界面,但如果你选择使用这种方法尝试类似:

Activity mActivity;

@Override
public void onAttach(Activity activity) {
      super.onAttach(activity);   

    this.mActivity = activity;
}

以避免类型NullPointerException错误

if(this.mActivity != null){
       this.mActivity.someMethod();
}

答案 6 :(得分:0)

如果你知道片段不会在另一个活动中,那么这是安全的。您也可以使用instanceof进行检查,以确保它是正确的类型。 有一些可能性,其中getActivity()可能返回null(当片段未附加时),因此检查活动是否为空甚至更好是一个好习惯:myFragment.isAdded()。否则,在调用activity.someMethod()时会出现NullPointerException。 所以安全的代码是:

if (isAdded() && getActivity() instanceof ParentActivity){
    ParentActivity activity = (ParentActivity) getActivity();
    activity.someMethod();
}

当然还有其他一些方法,比如将侦听器传递给片段,或者使用像Guava或Otto这样的共享事件总线,这些方法也有其优点和缺点。最简单的方法是上面描述的方法,如果你仔细使用它(检查null,更正类),它将按预期工作。