Android, Eclipse: что означает ошибка "Нет расширенного кода операции"?
При попытке отладки Android-приложения в Eclipse я получил следующее сообщение
Dx trouble writing output: No expanded opcode for 00412995 ExtractorBase.java:101@0006:
invoke-direct v0:N0001Lorg/xml/sax/InputSource;, v2:Ljava/io/Reader;,
org.xml.sax.InputSource.<init>:(Ljava/io/Reader;)V
Что в мире это значит?
Спасибо
2 ответа
Похоже, что у вас может быть больше ссылок на поля или методов (на самом деле, существует жесткое ограничение в 64 КБ).
Если у вас очень большой проект, вы можете столкнуться с этим ограничением.
Вы можете использовать try, чтобы избавиться от ненужных ссылок (вручную удаляя ненужные вещи из вашего проекта), или связываться с Proguard, который может сделать это автоматически.
Как уже упоминалось @Booger, существует максимальное количество полей, методов и классов, которые вы можете объявить в приложении для Android. Фактически, если вы посмотрите на саму инструкцию байт-кода dalivk, то увидите, что идентификаторы имеют максимум 64 КБ.
Сообщение об ошибке исходит от инструмента Android DX, который запускается всякий раз, когда вы компилируете свой код Android. Из открытого исходного кода Android вот код, который выдает это исключение:
private Dop findExpandedOpcodeForInsn(DalvInsn insn) {
Dop result = findOpcodeForInsn(insn.getLowRegVersion(), insn.getOpcode());
if (result == null) {
throw new DexException("No expanded opcode for " + insn);
}
return result;
}
Если вы углубитесь в дерево вызовов функций findOpCodeForInsn, вы окажетесь в одном из классов форматов, которые определяют инструкцию dalvik. В вашем случае это будет Form35c/3rc. И здесь, есть проверка, может ли идентификатор соответствовать короткому целому числу:
public boolean isCompatible(DalvInsn insn) {
....
CstInsn ci = (CstInsn) insn;
int cpi = ci.getIndex();
if (! unsignedFitsInShort(cpi)) {
return false;
}
Существуют новые расширенные байт-коды, которые разрабатываются и в будущем могут вместить большие идентификаторы, но они недоступны.
Между тем, вы не можете ничего сделать, кроме как сократить размер ваших методов. Для больших проектов, которые включают в себя несколько jar-файлов, это означает, что нужно пройти через них и попытаться найти неиспользуемые библиотеки, которые вы можете удалить.