【问题标题】:Android: Is there a way around SuperNotCalledException?Android:有没有办法绕过 SuperNotCalledException?
【发布时间】:2011-12-11 09:46:41
【问题描述】:

我正在尝试覆盖从 Activity 派生的类(称为 NativeActivity),以便我可以设置自己用 Java 创建的内容视图,同时保留其其余功能。我必须使用 NativeActivity,因为它是在 Xperia Play 上获取触摸板输入的唯一方法。我需要重写的方法是 NativeActivity.onCreate() 方法,因为这是设置我不想要的内容视图的地方。问题是,如果我不在重写的 onCreate() 方法中调用 super.onCreate(),则会引发 SuperNotCalledException。这来自 Activity 类。但是 Activity.onCreate() 方法所做的只是设置一个布尔值:

        protected void onCreate(Bundle savedInstanceState) {
            mVisibleFromClient = !mWindow
                    .getWindowStyle()
                    .getBoolean(
                            com.android.internal.R.styleable.Window_windowNoDisplay,
                            false);
            mCalled = true;
        }

我可以使用 Activity.getWindow() 方法在我自己的代码中进行检查。不幸的是,mCalled 布尔值是私有的,所以我不能在我自己的代码中将它设置为 true。我似乎无法弄清楚如何绕过这个要求。有什么想法吗?

【问题讨论】:

    标签: android android-ndk


    【解决方案1】:

    在 Activity 上覆盖此方法时,必须调用 super.onCreate(savedInstance)

    深入研究代码,此检查似乎旨在确保任何自定义 Instrumentation 都能正常工作。在我们所有的自定义活动中,对某些方法调用 super 的要求是实现的意外结果。

    不详细说明为什么这是一个糟糕的 OOP 设计,我可以说至少在 onCreate() 方法中调用 super.onCreate(savedInstanceState) 很简单。从代码中可以看出,没有不好的副作用。

    【讨论】:

    • 不好的副作用来自 NativeActivity.onCreate() 方法。在 Java 中没有 super.super。重写方法的重点是我不想调用它。
    • @user1002212 我不确定我是否理解你。不调用 super.onCreate() 只是个人愿望吗?
    • 这不是私人的,这是一个要求。如我上面的问题所述,我的类扩展了 NativeActivity,而不是 Activity。我想避免调用 NativeActivity.onCreate(如果我调用 super.onCreate 会发生这种情况),因为在 NativyActivity.onCreate 中它设置了内容视图(我不想这样做)。
    • @user1002212 - 在这种情况下,您可能根本不想从 NativeActivity 继承;派生类试图删除基类添加的特性的类层次结构很奇怪。当然,缺点是你必须复制 NativeActivity 提供的所有你想要的东西。
    • 谢谢,这在大多数情况下都适用于 Activity 的子类,但是对于 NativeActivity 也有一个本地组件。为了直接对 Activity 进行子类化,我还必须复制该组件(这比我感兴趣的工作要多)。无论如何,我最终以不同的方式解决了我原来的问题,所以我根本不需要这个。
    【解决方案2】:

    我从研究 Activity 的源代码中发现的一件事是,您可以在基本 Activity 类中调用将 mCalled 设置为 true 的方法之一,这些方法在子类中不会被覆盖,并且在基本 Activity 中什么也不做班级。所以在 NativeActivty 的情况下,可以调用类似 super.onRestart(); 的东西,因为这个类没有被 NativeActivity 覆盖,如下所示,它在 Activity 类中没有做任何事情:

    protected void onRestart() {
        mCalled = true;
    }
    

    这很老套,可能会在未来的某个版本中被打破,但如果您不想仅仅因为一个简单的布尔值而不得不重新创建 Activity 的整个子类,这可能是一个快速的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 2020-04-15
      • 1970-01-01
      • 2021-04-11
      • 2011-08-05
      相关资源
      最近更新 更多