通过onCreate方法将自定义参数传递给父活动会产生令人困惑的linter错误

问题描述 投票:1回答:2

为什么不通过onCreate方法将自定义参数传递给父活动,而将root方法覆盖给父活动,却导致以下linter错误:

覆盖方法应调用super.onCreate

背景

例如,我有一个MainActivity类,该类从ParentActivity扩展而来,该类扩展了Android的Activity。

example inheritance

UML Generator

为了使我的应用程序更加抽象,我正在尝试处理ParentActivity中的一些开发人员在开发和使用MainActivity时不需要看到的内容。

我有几个参数要传递给ParentActivity,例如booleans打开和关闭日志功能,但是似乎不建议通过onCreate()方法传递它们,因为这会引发linter错误。我将提出一个单独的问题,有关使用自定义方法或直接设置父字段将这些参数向上传递给自定义父类的最佳做法的最佳实践,但是我一直在寻求验证我目前对为什么不建议这样做的理解。现有的onCreate方法和其他参数。

尝试过的内容

作为起点,如果我有一些基本的MainActivity和ParentActivity:

代码0.1

public class MainActivity extends ParentActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //Do stuff
    }
}
public class ParentActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //Do stuff
    }
}

然后尝试将其他参数添加到onCreate,例如一个布尔值,用于在ParentActivity中打开/关闭某些记录器功能:

代码0.2

public class MainActivity extends ParentActivity{
    boolean logOn = true;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState, logOn);
        //Do stuff
    }
}
public class ParentActivity extends Activity{
    // No longer overriding Activity.onCreate() due to diff in params
    protected void onCreate(Bundle savedInstanceState, boolean logOn){
        super.onCreate(savedInstanceState);
        //Do stuff
    }
}

[Android Studio首先警告我,我没有重写父级的方法,这很有意义,因为它具有不同的参数计数,但是后来我认为我可以删除@Override并称其为好,因为我仍在调用[ C0],将把saveedInstanceState传递给Activity,而我仍在从MainActivity将SavedInstanceState传递给ParentActivity。在这一点上,我遇到了我的第一个未知问题:回到MainActivity,我收到一个linter错误,指出

覆盖方法应调用super.onCreate

令人困惑的是,我确实在出现此错误的位置下方直接致电super.onCreate(savedInstanceState)。尽管错误消息的内容不太丰富,但我可以通过在已存在的对super.onCreate(savedInstanceState, logOn)的调用的正上方调用super.onCreate(savedInstanceState)来消除错误,即::

代码0.3

super.onCreate(savedInstanceState, logOn)

[使用Android Studio查看工具提示的内联文档,我看到public class MainActivity extends ParentActivity{ boolean logOn = true; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); super.onCreate(savedInstanceState, logOn); //Do stuff } } public class ParentActivity extends Activity{ // No longer overriding Activity.onCreate() due to diff in params protected void onCreate(Bundle savedInstanceState, boolean logOn){ super.onCreate(savedInstanceState); //Do stuff } } 正在从Activity中调用onCreate方法(即ParentClass的父类),而super.onCreate(savedInstanceState);正在正在调用ParentClass的onCreate方法。考虑到典型的继承,并匹配参数的长度和类型,这是有道理的。

对我来说没有意义的是为什么我必须在MainActivity中调用Activity的onCreate方法。为什么在ParentActivity中对onCreate的调用不够用?即为什么Code 0.2会引发linter错误:

覆盖方法应调用super.onCreate

?我注意到,按照@ super.onCreate(savedInstanceState, logOn);的注释,代码0.2可以编译并在我的示例智能手机上运行,​​但是仍然存在linter错误。

java android inheritance overriding oncreate
2个回答
0
投票

IDE将在编译greeble31时检查@CallSuper 注释


0
投票

我认为不必担心太多,因为问题仅限于皮棉警告。您所做的事情有些复杂,以至于短毛猫无法跟随。您的程序实际上不是错误的。

您可以禁止显示警告({@link Activity#onCreate}),或直接忽略它。

...我可以只移除@SupressLint并称其为好...

[不太确定我是否同意你的观点,在这里...删除@Override批注实际上无济于事; linter / compiler仍然知道什么是替代,什么不是。我认为注释很有用,因为IDE会告诉您think是否覆盖了方法,但实际上却不是,即由于签名不匹配或某些原因(例如@Override)。 >

建议的方法

FWIW,我将以不同的方式解决此问题。 (请注意,代码0.3实际上导致对基类heretwo

调用;这可能是非法的。)我只是更改方法名称(以反映配置和创建之间的语义区别),并存储一些状态基类中的信息:
onCreate()

这实际上只是一个品味问题。

有时人们没有意识到Android可以自己重新创建活动,例如在恢复应用程序的堆栈状态时。 (这就是为什么您希望能够将public class MainActivity extends ParentActivity{ boolean logOn = true; @Override protected void onCreate(Bundle savedInstanceState){ configure(logOn); //Required, per base class specification super.onCreate(savedInstanceState); //Do stuff } } public abstract class ParentActivity extends Activity{ boolean logOn; boolean configured = false; /** Subclasses are obligated to call this before calling super.onCreate() */ protected void configure(boolean logOn) { this.logOn = logOn; this.configured = true; } @Override protected void onCreate(Bundle savedInstanceState){ if(!configured) throw new IllegalStateException("configure() not called prior to onCreate()"); super.onCreate(savedInstanceState); //Do stuff } @Override protected void onDestroy() { configured = false; //(just being pedantic) } } 状态串行化和反序列化到包中/从包中反序列化的原因; b / c可能无法使用第一次导致创建Activity的相同工作流程来重新创建Activity状态)。

但是,我认为这不会成为您的问题,因为ParentActivity(我已经声明为abstract)总是要通过一个具体的子类实例化,并且所有子类都可以保证在其configure()方法中调用onCreate()。 (IOW,ParentActivity没有清单条目,因此系统永远不会尝试自行实例化基类ParentActivity。)

只是需要注意的事情。

© www.soinside.com 2019 - 2024. All rights reserved.