安卓系统,超级未调用异常错误

3

我有两个片段,MyFirst片段和MySecond片段。MySecond片段继承自MyFirst片段。

类定义如下:

public class MyFirstFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        ...                
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
        ...
            // Check view and map, request to recreate if each of them is null
            if(MyFirstFragment.this.getView() == null  ||  googleMap == null) {
                Toast.makeText(getActivity().getApplicationContext(), R.string.my_message, Toast.LENGTH_LONG).show();
                return;
            }
        }
    }

public class MySecondFragment extends MyFirstFragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        ...
        }

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

我的问题是,在MySecondFragment的onActivityCreated()方法中,super.onActivityCreated(savedInstanceState); 调用了它的父类。由于我想隐藏这个方法在父类中的功能(对此片段没有用处),因此我已经在MySecondFragment中添加了onActivityCreated()方法。
问题是,如果我删除这行代码,那么我会运行时错误,抛出“SuperNotCalledException”。
你认为呢?看起来我必须扩展Fragment类,而不是扩展MyFirstFragment。我在MyFirstFragment中有一些变量,我需要它们在MySecondFragment中使用。

我不明白为什么你想要删除那行代码?它会引起任何问题吗? - Caner
他想将功能隐藏在父片段中。尝试从MySecondFragment中删除整个onActivityCreated方法。 - Mcingwe
@Caner,正如您所看到的,在超级方法中有一个Toast消息。然后在第二个片段中显示,这不应该显示。那个Toast消息属于第一个片段而不是第二个片段。 - Hesam
如果你重写了方法,你需要调用 super()。对于你来说,super() 来自于第一个 Fragment。为什么你不期望 Toast 呢? - Mcingwe
你可能只是弄乱了你的层次结构。很有可能你只需要调整继承层次(MyFirstFragment继承MySecondFragment)。如果这不起作用,你可能需要另一层抽象,两个Fragments都从中继承。 - deekay
显示剩余2条评论
3个回答

2

您可以在MyFirstFragment中编写一个新的函数testFunction(Bundle savedInstanceState),其中调用super.onActivityCreated(savedInstanceState);

MySecondFragmentonActivityCreated中调用此testFunction(Bundle savedInstanceState)而不是super.onActivityCreated(savedInstanceState);,即:

MyFirstFragment中:

testFunction(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
}

MySecondFragment 中。
public void onActivityCreated(Bundle savedInstanceState) {
    super.testFunction(savedInstanceState);
...
}

我不是很清楚您想要绕过MyFirstFragmentonActivityCreated的基本需求,但您可以这样做。

工作得很好,不错的解决方案,虽然我不确定是否是一种干净的方式。但是它能正常工作,谢谢 ;) - Hesam

2

无论如何都需要调用Fragment的实现。如果您不想调用MyFirstFragment的实现,有几种解决方案:

  1. 最干净的方法是,给MyFirstFragment和MySecondFragment一个共同的祖先,这将基本上是MyFirstFragment,除了onActivityCreated()之外。两个活动将直接从它继承。

  2. 调用super,但是添加一个变量到bundle中,以让MyFirstFragment知道这次不应该调用它的实现。

  3. 在MySecondFragment中只需扩展Fragment


-1

你应该总是调用super方法。只需在MySecondFragment.onActivityCreated()方法中设置所需的变量,然后在之后使用它们即可。为了隐藏功能,你可以始终检查调用对象类,但这违反了面向对象编程的继承原则。


但它确实在调用super。SecondFragment调用super.onActivityCreated,这是FirstFragment的onActivityCreated,而FirstFragment也调用super.onActivityCreated,这会上溯到Fragment。 - Flynny75
据我所理解,OP不想调用super.onActivityCreated(),因为某些代码不适用于MySecondFragment.onActivityCreated()。所以他需要仅在调用对象的类为MyFirstFragment时运行代码,或者正如mick88指出的那样,最好的解决方案是让MyFirstFragment和MySecondFragment都继承一个具有共同代码的抽象祖先,在其onActivityCreated()中实现公共代码,子类应在其onActivityCreated()方法中实现其特定代码。 - tkolev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接