1

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

Pythogen
  • 591
  • 5
  • 25
  • 1
    If you need a default constructor just for the hell of it, you can have it as `public custom_row_adapter() { }`. – PM 77-1 Mar 28 '16 at 02:24
  • You are saying it builds fine, but the error only happens when you are generating a signed APK? Sounds fishy to me. – chiliNUT Mar 28 '16 at 02:59
  • if I build>build apk it generates the debug apk with no errors, but when I try to generate a signed apk, the error occurs. – Pythogen Mar 28 '16 at 03:02

6 Answers6

3

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");
}
bwt
  • 17,292
  • 1
  • 42
  • 60
1

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.

MolonLabe
  • 168
  • 2
  • 8
1

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); 
    }
Community
  • 1
  • 1
Paul MacGuiheen
  • 628
  • 5
  • 17
  • Alright, thanks for the link. After reading it, I have come to the conclusion that I need to manually direct the ArrayAdapter to a superclass constructor manually. How would I achieve this? You said "override one of the ones it does have" What exactly do you mean by one of the ones? (Forgive me if it's obvious, I just can't seem to wrap my head around this whole thing) – Pythogen Mar 28 '16 at 02:47
  • POST EDIT: Thankyou for adding those lines of code. But after trying those lines of code, I still got the no default constructor error. I guess no arguments means absolutely zero. – Pythogen Mar 28 '16 at 02:56
  • @Pythogen You got rid of the zero-param constructor right? Also make sure you don't have any other constructors on your class that don't have a call to super on their first line – Paul MacGuiheen Mar 28 '16 at 03:05
  • Yeah, 2 constructors, the default one you told me to use and my custom one that has the super on its first line. – Pythogen Mar 28 '16 at 03:21
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.

  • From here do you mean my custom_row_adapter.java? And where do I put my default constructor then? (Well not where but how do I do it without requiring arguments) Could you post more information and maybe include the constructor from the first code example you gave? – Pythogen Mar 28 '16 at 03:18
  • @Pythogen no, I mean from your **context**, maybe an [Activity](http://developer.android.com/reference/android/app/Activity.html) or a [Service](http://developer.android.com/reference/android/app/Service.html). – António Pedro Fraga Mar 28 '16 at 03:21
  • @Pythogen since this class is extending an **ArrayAdapter** you don't need to place a constructor in it. – António Pedro Fraga Mar 28 '16 at 03:25
  • are you saying I should just copy and paste the custom_row_adapter to the file containing the array adapter? (Sorry if that was not at all what you were saying) The file that calls the custom_row_adapter has this in it: ListAdapter picAdapt = new custom_row_adapter(this, picList, url, fullUrl); and then the custom_row_adapter class is in a new Java File, and if I delete the constructor totally, I get the message that there is no default constructor. – Pythogen Mar 28 '16 at 03:29
  • It would be nice to know the type of those arguments. Anyway, it's probably because there's not a constructor with that type/number of arguments in the **ArrayAdapter** class. – António Pedro Fraga Mar 28 '16 at 03:37
  • I'll post some more pictures and hope it will help you guys, thanks for putting up with me:P – Pythogen Mar 28 '16 at 03:39
0

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

heisbrandon
  • 1,180
  • 7
  • 8
0

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.

Community
  • 1
  • 1
Cache Staheli
  • 3,510
  • 7
  • 32
  • 51