Pythogen
Pythogen

Reputation: 640

How to add a default contructor

Hope I am not duplicating a question here, but all of the ones I found on stack exchange dont seem to fit my need.

Here is a snippet of my code:

public class custom_row_adapter extends ArrayAdapter<Integer> {
     custom_row_adapter(Context context, ArrayList<Integer> picId, String url, String fullUrl) {
         super(context, R.layout.activity_custom_row_adapter, picId);
}
     //Do stuff

Everything works fine in the app, now I try to generate a signed apk and I get a nice little error that I need a default constructor. So I decide that I will add one, now my code looks like this:

public class custom_row_adapter extends ArrayAdapter<Integer> {
    public custom_row_adapter() {
        super();
}
     custom_row_adapter(Context context, ArrayList<Integer> picId, String url, String fullUrl) {
         super(context, R.layout.activity_custom_row_adapter, picId);
}
//Do Stuff

Now I get a new error that it can't find a suitable constructor for ArrayAdapter()

So I get on google and find a couple posts and one tells me I can bypass that error by searching Instantiable in the Inspections tab and turning it to WARNING that it will fix it. Didn't work.

So how do I fix this? Thanks in advance.

EDIT: for those of you saying I can just add public custom_row_adpater(){} enter image description here

EDIT 2: Here are some more pictures, pay attention to the Error on bottom left:

What Works in debug:What works in Debug

Paul G's Answer:Paul G's answer

Defualt Constructor:default constructor

No Constructor:No constructor

Upvotes: 1

Views: 633

Answers (6)

Cache Staheli
Cache Staheli

Reputation: 3673

I hope that I understand what you are asking.

Solution

Because ArrayAdapter does not have a default "no-arg" constructor, you must supply some arguments. I.e. instead of putting

public custom_row_adapter() {
    super();
}

You would instead need to specify (at least) two arguments. See the Javadocs for more information.

public custom_row_adapter() {
    super(context, resource);
}

What context and resource are needs to be determined by you. Since it's possible you might not need this constructor, they could possibly be null and some int, like 0 or -1.

Why

By default, when no constructor is provided for your class, Java automatically builds you one that does nothing (essentially). However, as soon as you create another constructor, the default one (custom_row_adapter()) "disappears". See this post for additional info.

Also, by default, the first call of the no-arg constructor (custom_row_adapter()) is implicitly super(); (see Java SE). Since ArrayAdapter doesn't have a default no-argument constructor, this is invalid, and you must supply arguments to it.

Upvotes: 0

Philippe Banwarth
Philippe Banwarth

Reputation: 17755

This error means that for some reason the lint (wrongly) thinks that your adapter should be instantiatable. This apply to objects which may be instantiated by the system like activities, broadcast receivers, but not to adapters because they are always instantiated in the application's code. For example commonly used adapters like ArrayAdapter or SimpleCursorAdapter don't have a default constructor.

You can try to make Android Studio come to his senses, for example update the build tools, clean the workspace, delete the build directory... If it doesn't work you can add the requested (and useless) default contructor :

public custom_row_adapter() {
    super(null , 0);
    throw new RuntimeException("This is a workaround and should not be used");
}

Upvotes: 3

heisbrandon
heisbrandon

Reputation: 1220

From JavaSE doc:

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

Giving an empty constructor body for a default constructor is the same as putting a super call i.e.

public custom_row_adapter() {
    super();
}

is the same as

public custom_row_adapter() {}

So it results in an error because there is no default constructor in the superclass, and explicit constructor invocation is required. In this case you could overload your constructor and call to that with this(args), or call to some superclass constructor with super(args).

Reference: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.7

Upvotes: 0

Since you are extending an ArrayAdapter you can instantiate you're object from here:

Custom_row_adapter customAdapter = new Custom_row_adapter(this, android.R.layout.simple_spinner_item, insertIntegerArray);

If you want some extra arguments in your class then create a custom contructor:

 public Custom_row_adapter(Context context, int resource, Integer[] array, arg extraArg) {
    super(context, resource, array);
    this.extraArg = extraArg;
 }

My advice is to rename your class to Custom_row_adapter. It's a good practice to start a class name with an Upper Case char.

Upvotes: 0

Paul MacGuiheen
Paul MacGuiheen

Reputation: 638

ArrayAdapter does not have a default i.e.zero-param constructor so you must override one of the ones it does have. You can find more info here android - There is no default constructor for ArrayAdapter

public class custom_row_adapter extends ArrayAdapter<Integer> { 
    public custom_row_adapter(Context context, int resource) {
        super(context, resource); 
    }

Upvotes: 1

MolonLabe
MolonLabe

Reputation: 168

It's because ArrayAdapter doesn't define a no-argument constructor. That's what the compiler looks for when you call super() with no parameters. It needs, at a minimum, a Context and a resource (int) to initialize itself.

Upvotes: 1

Related Questions