Как добавить конструктор по умолчанию

Надеюсь, я не дублирую здесь вопрос, но все вопросы, которые я нашел при обмене стеками, мне не подходят.

Вот фрагмент моего кода:

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

В приложении все работает нормально, теперь я пытаюсь сгенерировать подписанный apk и получаю небольшую симпатичную ошибку: мне нужен конструктор по умолчанию. Итак, я решил, что добавлю еще один, теперь мой код выглядит так:

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

Теперь я получаю новую ошибку: не удается найти подходящий конструктор для ArrayAdapter().

Итак, я захожу в Google и нахожу пару сообщений, и в одном из них говорится, что я могу обойти эту ошибку, выполнив поиск Instantiable на вкладке Inspections и переключив его на WARNING, что он исправит это. Не сработало.

Так как мне это исправить? Заранее спасибо.

ИЗМЕНИТЬ: для тех из вас, кто говорит, что я могу просто добавить public custom_row_adpater(){} введите описание изображения здесь

РЕДАКТИРОВАТЬ 2: вот еще несколько изображений, обратите внимание на ошибку внизу слева:

Что работает при отладке:  Что работает в отладке

Ответ Пола Джи:  Ответ Пола Дж.

Конструктор по умолчанию:  конструктор по умолчанию

Без конструктора:  Без конструктора


person Pythogen    schedule 28.03.2016    source источник
comment
Если вам нужен конструктор по умолчанию, черт возьми, вы можете использовать его как public custom_row_adapter() { }.   -  person PM 77-1    schedule 28.03.2016
comment
Вы говорите, что сборка выполняется нормально, но ошибка возникает только при создании подписанного APK? Для меня это звучит подозрительно.   -  person chiliNUT    schedule 28.03.2016
comment
если я создаю ›build apk, он генерирует отладочный apk без ошибок, но когда я пытаюсь создать подписанный apk, возникает ошибка.   -  person Pythogen    schedule 28.03.2016


Ответы (6)


Эта ошибка означает, что по какой-то причине lint (ошибочно) считает, что ваш адаптер должен быть инстанцируемым. Это применимо к объектам, которые могут быть созданы системой, например действиям, широковещательным приемникам, но не к адаптерам, поскольку они всегда создаются в коде приложения. Например, часто используемые адаптеры, такие как ArrayAdapter или SimpleCursorAdapter, не имеют конструктора по умолчанию.

Вы можете попробовать заставить Android Studio прийти в себя, например обновить инструменты сборки, очистить рабочее пространство, удалить каталог build ... Если это не сработает, вы можете добавить запрошенный (и бесполезный) конструктор по умолчанию:

public custom_row_adapter() {
    super(null , 0);
    throw new RuntimeException("This is a workaround and should not be used");
}
person bwt    schedule 01.04.2016
comment
Спасибо! Чего мне не хватало, так это использования null, 0 для параметров супер - person Pythogen; 02.04.2016

Это потому, что ArrayAdapter не определяет конструктор без аргументов. Это то, что ищет компилятор, когда вы вызываете super () без параметров. Для инициализации ему необходимы как минимум контекст и ресурс (int).

person MolonLabe    schedule 28.03.2016
comment
Я новичок в Java, но понимаю, что вы говорите, но не знаю, как это исправить. Не могли бы вы дать решение в виде кода? - person Pythogen; 28.03.2016
comment
Просто удалите вызов super () в конструкторе без аргументов. - person MolonLabe; 28.03.2016

ArrayAdapter не имеет конструктора iezero-param по умолчанию, поэтому вы должны переопределить один из имеющихся. Дополнительную информацию можно найти здесь android - для ArrayAdapter <нет конструктора по умолчанию / а>

public class custom_row_adapter extends ArrayAdapter<Integer> { 
    public custom_row_adapter(Context context, int resource) {
        super(context, resource); 
    }
person Paul MacGuiheen    schedule 28.03.2016
comment
Хорошо, спасибо за ссылку. Прочитав его, я пришел к выводу, что мне нужно вручную направить ArrayAdapter в конструктор суперкласса. Как мне этого добиться? Вы сказали переопределить один из имеющихся. Что именно вы имеете в виду под одним из них? (Простите, если это очевидно, я просто не могу осмыслить все это) - person Pythogen; 28.03.2016
comment
POST EDIT: спасибо за добавление этих строк кода. Но после того, как я попробовал эти строки кода, я все еще получил ошибку конструктора по умолчанию. Думаю, отсутствие аргументов означает абсолютный ноль. - person Pythogen; 28.03.2016
comment
@Pythogen Вы избавились от конструктора с нулевыми параметрами, верно? Также убедитесь, что в вашем классе нет других конструкторов, у которых нет вызова super в их первой строке. - person Paul MacGuiheen; 28.03.2016
comment
Да, 2 конструктора, один по умолчанию, который вы мне сказали использовать, и мой собственный, в первой строке которого есть super. - person Pythogen; 28.03.2016

Поскольку вы расширяете ArrayAdapter, вы можете создать экземпляр объекта отсюда:

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

Если вам нужны дополнительные аргументы в своем классе, создайте собственный конструктор:

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

Я советую переименовать ваш класс в Custom_row_adapter. Рекомендуется начинать имя класса с символа верхнего регистра.

person António Pedro Fraga    schedule 28.03.2016
comment
Отсюда вы имеете в виду мой custom_row_adapter.java? А где мне тогда поставить конструктор по умолчанию? (Ну, не где, но как мне это сделать, не требуя аргументов) Не могли бы вы опубликовать дополнительную информацию и, возможно, включить конструктор из первого примера кода, который вы указали? - person Pythogen; 28.03.2016
comment
@Pythogen нет, я имею в виду из вашего контекста, возможно, Activity или Service. - person António Pedro Fraga; 28.03.2016
comment
@Pythogen, поскольку этот класс расширяет ArrayAdapter, вам не нужно размещать в нем конструктор. - person António Pedro Fraga; 28.03.2016
comment
Вы говорите, что мне нужно просто скопировать и вставить custom_row_adapter в файл, содержащий адаптер массива? (Извините, если это было совсем не то, что вы говорили) В файле, который вызывает custom_row_adapter, есть следующее: ListAdapter picAdapt = new custom_row_adapter (this, picList, url, fullUrl); а затем класс custom_row_adapter находится в новом файле Java, и если я полностью удалю конструктор, я получаю сообщение о том, что конструктора по умолчанию нет. - person Pythogen; 28.03.2016
comment
Было бы неплохо узнать тип этих аргументов. В любом случае, вероятно, потому, что в классе ArrayAdapter нет конструктора с таким типом / количеством аргументов. - person António Pedro Fraga; 28.03.2016
comment
Я выложу еще несколько фотографий и надеюсь, что это поможет вам, ребята, спасибо, что терпите меня: P - person Pythogen; 28.03.2016

Из документа JavaSE:

Если тело конструктора не начинается с явного вызова конструктора и объявляемый конструктор не является частью первичного класса Object, тогда тело конструктора неявно начинается с вызова конструктора суперкласса «super ();», вызова конструктора класса его прямой суперкласс, не принимающий аргументов.

Предоставление пустого тела конструктора для конструктора по умолчанию аналогично помещению супервызова, т.е.

public custom_row_adapter() {
    super();
}

такой же как

public custom_row_adapter() {}

Таким образом, это приводит к ошибке, потому что в суперклассе нет конструктора по умолчанию, и требуется явный вызов конструктора. В этом случае вы можете перегрузить свой конструктор и вызвать его с помощью this (args) или вызвать какой-либо конструктор суперкласса с помощью super (args).

Ссылка: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.7.

person heisbrandon    schedule 31.03.2016

Надеюсь, я понимаю, о чем вы спрашиваете.

Решение

Поскольку ArrayAdapter не имеет конструктора без аргументов по умолчанию, вы должны указать некоторые аргументы. Т.е. вместо того, чтобы положить

public custom_row_adapter() {
    super();
}

Вместо этого вам нужно будет указать (как минимум) два аргумента. См. Javadocs для получения дополнительной информации.

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

Что такое context и resource, должно быть определено вами. Поскольку возможно, вам не понадобится этот конструктор, это могут быть null и некоторые int, например 0 или -1.

Почему

По умолчанию, когда для вашего класса не предусмотрен конструктор, Java автоматически создает конструктор, который ничего не делает (по сути). Однако, как только вы создадите другой конструктор, конструктор по умолчанию (custom_row_adapter()) исчезнет. Дополнительную информацию см. В этом сообщении.

Кроме того, по умолчанию первый вызов конструктора без аргументов (custom_row_adapter()) неявно super(); (см. Java SE). Поскольку ArrayAdapter не имеет конструктора без аргументов по умолчанию, это недопустимо, и вы должны предоставить ему аргументы.

person Cache Staheli    schedule 01.04.2016