I'm trying to make a simple Android application based on a guide. I am using the code below, but it is giving me several errors. It is complaining while trying to override the onCreate() method. The exact error is below. Can anyone explain what mistake I am making here?
package com.bignerdranch.android.geoquiz;
import android.os.Bundle;
public class CheatActivity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat);
}
}
The exact errors:
The method onCreate(Bundle) is undefined for the type Object
The method setContentView(int) is undefined for the type CheatActivity
The method onCreate(Bundle) of type CheatActivity must override or implement
a supertype method
import android.app.Activity;
public class CheatActivity extends Activity {
You should extend from Activity class. Because you are just creating new class without any methods which can be overridden from parent class.
As Anatol said, you have to add extends Activity.
If you didn't know that, the only method you have is implemented when extending from Activity.
I would recommend you to create Activities with your IDE's wizard. And you will avoid having to add them manually to the manifest and adding unimplemented methods.
Related
Question
As defined in the pseudo-code below, why does an inherited public method (setContentView) of a parent class (MyCustomClassA) defined in a separate package (packageB) not resolve despite the public methods directly defined in said parent class (myPublicMethod) do resolve?
As both myPublicMethod and setContentView are public methods, I'm quite confused as to why one is able to resolve while the other is not.
Minimal Example Pseudo Code
A summary of the hierarchy is shown in the pseudo-code below as well as comments describing the tooltips and errors shown by Android Studio:
package packageA;
public abstract class BaseClass extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(#LayoutRes int layoutResID)
}
}
package packageB;
import packageA.BaseClass
public abstract class MyCustomClassA extends BaseClass{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(#LayoutRes int layoutResID)
}
}
package packageB;
import packageB.MyCustomClassA
public abstract class MyCustomClassB extends MyCustomClassA{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(#LayoutRes int layoutResID)
myPublicMethod(); // Tooltip shows this resolves to packageB.MyCustomClassA
}
public void myPublicMethod() {
}
}
package packageC;
import packageB.MyCustomClassA
public abstract class MyCustomClassC extends MyCustomClassA{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(layoutID); // Error: Cannot resolve method 'setContentView' in MyCustomClassC
myPublicMethod(); // Tooltip shows this resolves to packageB.MyCustomClassA
}
}
What have I tried so far:
Using Android Studio I Ctrl+click the parent classes and verify that they are all pointing to the correct classes.
I Build -> Clean Project and Invalidate Caches and Restart to ensure nothing in the Cache is outdated.
I created a dummy class MyCustomClassB to test whether the setContentView method would be resolvable within the same package. It does resolve. This led me to think it might be a package/protected or otherwise access issue, but as setContentView is a public method in Activity, I'm stuck for additional troubleshooting ideas.
Read this , this, and this among several others related to inheritance, and everything I read only further confirms that this should be possible.
Is it possible this is gradle related? I've gone through the project and app level gradle files in great detail as well, trying to eliminate any possible duplicate dependencies, or things that might cause aliasing, but apart from that I've hit a wall for ideas. Any other ideas of where to continue looking for an error or can you explain why this fundamentally doesn't work (i.e. this is not an error in the code, but an error in my understanding of inheritance)?
I attempted to build despite the linter errors and received a bit more helpful of an error. This appeared to be the origin of the origin of the build errors, which was thrown at the definition of public abstract class MyCustomClassC extends MyCustomClassA:
error: cannot access BaseClass
So it looks like MyCustomClassC is able to access MyCustomClassA without issue, but not the parent (BaseClass) of MyCustomClassA.
Looking back at my gradle build files, I seem to have found the issue. I previously had only this dependency in the MyCustomClassC app-level gradle build file:
dependencies {
implementation(project(":packageBModule"))
}
while the dependencies for packageB where in their own build file.
dependencies {
implementation(project(":packageAModule"))
}
but after adding the dependencies of both to my packageCModule build file, i.e.:
dependencies {
implementation(project(":packageBModule"))
implementation(project(":packageAModule"))
}
everything resolves. I was under the impression that I did not have to specify dependencies of all parent classes within each subclass module, and they would be brought in via the inheritance, but this appears to be an incorrect assumption. Looks like I need to finally bite the bullet and start reading through the gradle docs in further detail as I'd guess there is a more optimal way to manage dependencies for inherited classes rather than just copying and pasting them in an ever growing list for an ever deeper inheriting subclass.
Why does passing custom parameters to a parent activity through an onCreate method, while leaving overriding the root method to the parent, result in the following linter error:
Overriding method should call super.onCreate
Background
For example, I have a MainActivity class that extends from ParentActivity that extends Android's Activity.
UML Generator
In order to make my app more abstract I am trying to handle several things in ParentActivity that the developer need not see in their development and use of MainActivity.
I have several parameters I would like to pass to the ParentActivity, like booleans turning on and off log functionalities, but it seems passing them through the onCreate() method is not ~~possible~~ recommended since this throws linter errors. I will make a separate question regarding the best practices for passing such parameters upward to custom parent classes using custom methods or directly setting parent fields, but I was looking to verify my current understanding of why this is not ~~possible~~ recommended through the existing onCreate method and additional parameters.
What has been tried
As a starting point, if I have some basic MainActivity and ParentActivity:
Code 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
}
}
and then try to add further parameters to onCreate, e.g. a boolean to turn on/off some logger functionality within ParentActivity:
Code 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 first warns me that I am not overriding the parent's method, which makes sense as it has a different parameter count, but then I thought I can just remove the #Override and call it good since I'm still calling super.onCreate(savedInstanceState) in ParentActivity, which will pass the savedInstanceState up to Activity, and I'm still passing the savedInstanceState to ParentActivity from MainActivity. At this point I encountered my first unknown issue: back in MainActivity, I get a linter error that states
Overriding method should call super.onCreate
Whats confusing is that I do call super.onCreate(savedInstanceState, logOn) directly below where I get this error. Although the error message is not too informative, I can get rid of the error by calling super.onCreate(savedInstanceState) directly above the already existing call to super.onCreate(savedInstanceState, logOn), i.e.:
Code 0.3
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
}
}
Looking at the tooltip inline doc using Android Studio, I see that super.onCreate(savedInstanceState); is calling the onCreate method from Activity (i.e the parent class of ParentClass) and super.onCreate(savedInstanceState, logOn); is calling the onCreate method of ParentClass. With typical inheritance in mind, and matching parameter lengths and types, this makes sense.
What doesn't make sense to me is why I have to call the onCreate method of Activity in MainActivity. Why does the call to onCreate within ParentActivity not suffice? i.e. why does Code 0.2 throw the linter error:
Overriding method should call super.onCreate
? I note, as per the comment by #greeble31 that Code 0.2 compiles, and runs on my example smartphone, but the linter error remains.
I don't think it's too much to worry about, since the problem is limited to a lint warning. You just did something a little too complicated for the linter to follow; your program is not, in fact, incorrect.
You could suppress the warning (#SupressLint), or simply ignore it.
...I can just remove the #Override and call it good...
Not too sure I agree with you, there... Removing the #Override annotation can't really help anything; the linter/compiler still knows what's an override and what's not. I consider the annotation useful b/c the IDE will tell you if you think you're overriding a method, but you're actually not, i.e. due to a signature mismatch or something (as here).
SUGGESTED APPROACH
FWIW, I would've solved this problem a little differently. (Note that code 0.3 actually results in two calls to the base class onCreate(); that's probably illegal.) I would just change the method name (to reflect a semantic distinction between configuration and creation), and store some state information in the base class:
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)
}
}
It's really just a matter of taste.
Sometimes people don't realize that Android can spontaneously create Activities on its own, like when it restores the back-stack state of your app. (This is why you want to be able to serialize and deserialize your Activity state to/from the bundle; b/c your Activity might not be re-created using the same workflow that caused its creation the first time).
I don't think that's going to be an issue for you, though, since ParentActivity (which I've declared as abstract) is always going to be instantiated via a concrete subclass, and all subclasses are guaranteed to call configure() in their onCreate() methods. (IOW, ParentActivity wouldn't have a manifest entry, so the system is never going to try to instantiate a base-class ParentActivity by itself.)
Just something to be aware of. (You had logOn set to a constant value in MainActivity, so if you were planning on changing that dynamically based on the app state, before calling configure()/super.onCreate(), just bear in mind that -- if you don't take steps to prevent it -- that information could be lost when your app is restored to the foreground.)
IDE will check #CallSuper annotation when on compilation {#link Activity#onCreate}.
I am facing a strange problem suddenly in android. I am creating layout .xml file in res>layout but from a class that extends activity, I can not access it. I have done this several a time but I can not figure out this strange problem. I restarted the eclipse, even the computer but no. When I go for setting the contentView it says something as below :
The method onCreate(Bundle) of type MainActivity must override or implement a supertype method
That is let I have created an xml file at res>layout named "whynot.xml" and from a activity when I try to set it like
setContentView(R.layout.whynot);
It shows red mark below and the above message.
you have to extends Activity and call super.onCreate(savedInstanceState) in the onCreate. For each callback of the Activity's lifecycle is mandatory to call its super
As the error says,
must override or implement a supertype method
you need the super call like
#Override
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle); // here
setContentView(...);
...
}
I'm trying to compile the sample code from the facebook sdk. Now I'm getting errors on all the
lines below #Override
example on the following lines
#Override
public void startActivityForResult(Intent intent, int requestCode)
I get a error that says:
the method startActivityForResult of type new must override super class type
could I just delete all the #Override
Whatever class you are extending is assumed to have a method declaration of startActivityForResult with exact return type and parameters. Check if you are following it. You can remove #Override and it will work, but by that you are saying, this method doesn't exist in your super class. Verify the class you perhaps extending. If this method is supposed to be invoked and you do not, something else will break.
Method signature looks fine. You don't extend android.app.Activity class.
public class MyActivity extends Activity {
...
I'm using PhoneGap. And read it and created my work.
http://docs.phonegap.com/en/1.9.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android
And i added this line in MyworkActivity.java:
super.loadUrl("file:///android_asset/www/index.html");
But when run as my project, get this error:
The method loadUrl(String) is undefined for the type Activity
How can i fix it?
When you are using PhoneGap, Your class is extended with DroidGap instead of Activity, so please check you have probably extended your class Activity.