Мгновенные приложения для Android: перенос существующего мультидекс-приложения в базовый/функциональный модуль?

Я переношу свое существующее мультидекс-приложение в приложение с мгновенным запуском и преобразую свое приложение в рекомендуемое структура проекта.

Было множество связанных с компиляцией проблем, которые были успешно решены, однако при попытке запустить устанавливаемый модуль «приложения» я столкнулся со следующей ошибкой, как указано ниже в трассировке стека.

Я подозреваю, что это связано с тем, что мой модуль baseFeature (предыдущее приложение с несколькими индексами) несовместим с архитектурой мгновенного приложения.

Любые подсказки о том, как лучше всего справиться с этим? Если кто-нибудь может указать, как существующее мультидекс-приложение будет перенесено на новую архитектуру мгновенного приложения, было бы здорово :)

Трассировки стека:

Error converting bytecode to dex:
Cause: InvokeDynamic not supported
com.android.dx.cf.iface.ParseException: InvokeDynamic not supported
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
    at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
    at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:720)
    at com.android.ide.common.internal.WaitableExecutor.waitForTasksWithQuickFail(WaitableExecutor.java:146)
    at com.android.builder.dexing.DexArchiveBuilder.processOutputs(DexArchiveBuilder.java:110)
    at com.android.builder.dexing.DexArchiveBuilder.convert(DexArchiveBuilder.java:91)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransformCallable.lambda$cacheMissAction$0(DexArchiveBuilderTransformCallable.java:236)
    at com.android.builder.utils.FileCache.lambda$createFile$1(FileCache.java:260)
    at com.android.builder.utils.FileCache.lambda$null$5(FileCache.java:443)
    at com.android.builder.utils.SynchronizedFile.doActionWithSingleProcessLocking(SynchronizedFile.java:291)
    at com.android.builder.utils.SynchronizedFile.write(SynchronizedFile.java:234)
    at com.android.builder.utils.FileCache.lambda$queryCacheEntry$6(FileCache.java:415)
    at com.android.builder.utils.SynchronizedFile.doActionWithSingleProcessLocking(SynchronizedFile.java:291)
    at com.android.builder.utils.SynchronizedFile.read(SynchronizedFile.java:217)
    at com.android.builder.utils.FileCache.queryCacheEntry(FileCache.java:391)
    at com.android.builder.utils.FileCache.createFile(FileCache.java:273)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransformCallable.getFromCacheAndCreateIfMissing(DexArchiveBuilderTransformCallable.java:185)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransformCallable.call(DexArchiveBuilderTransformCallable.java:147)
    at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransformCallable.call(DexArchiveBuilderTransformCallable.java:53)
    at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.android.dx.cf.iface.ParseException: InvokeDynamic not supported
    at com.android.dx.cf.cst.ConstantPoolParser.determineOffsets(ConstantPoolParser.java:226)
    at com.android.dx.cf.cst.ConstantPoolParser.parse(ConstantPoolParser.java:132)
    at com.android.dx.cf.cst.ConstantPoolParser.parseIfNecessary(ConstantPoolParser.java:124)
    at com.android.dx.cf.cst.ConstantPoolParser.getPool(ConstantPoolParser.java:115)
    at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:491)
    at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
    at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
    at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
    at com.android.builder.dexing.DexArchiveBuilderCallable.parseClass(DexArchiveBuilderCallable.java:86)
    at com.android.builder.dexing.DexArchiveBuilderCallable.call(DexArchiveBuilderCallable.java:70)
    at com.android.builder.dexing.DexArchiveBuilderCallable.call(DexArchiveBuilderCallable.java:43)
    ... 5 more
...while preparsing cst 0032 at offset 000000f1
...while parsing RangeDialogFragment.class

Execution failed for task ':installapp:transformClassesWithDexBuilderForDebug'.
    com.android.build.api.transform.TransformException:  java.lang.RuntimeException: java.lang.RuntimeException:  java.util.concurrent.ExecutionException:  java.util.concurrent.ExecutionException:  com.android.builder.utils.FileCache$FileCreatorException:  
    com.android.builder.dexing.DexArchiveBuilder$DexBuilderException: Unable to convert input to dex archive.

person prerak    schedule 28.05.2017    source источник
comment
Это больше похоже на проблему с зависимостью от Java 8 или ретролямбда, чем на проблему с несколькими индексами. См. связанный вопрос.   -  person pbaumann    schedule 31.05.2017
comment
Не уверен, я использую методы java8, но у меня нет ретролямбды. Я предполагаю, что одна из зависимостей может использовать его?   -  person prerak    schedule 03.06.2017


Ответы (1)


В настоящее время функциональные модули не поддерживают multidex, поэтому каждый функциональный модуль должен использовать один dex.

Общего решения этой проблемы нет, но я могу дать несколько советов.

  1. Попробуйте переместить код пользовательского интерфейса из базового функционального модуля в другой функциональный модуль. Библиотеки поддержки Android оказывают наибольшее влияние на количество методов, поэтому перемещение библиотек поддержки из модуля base-feature в модуль ui-feature должно помочь.
  2. Play Services — еще одна крупная библиотека, влияющая на количество методов. Если можете, не добавляйте SDK для игровых сервисов целиком, а используйте его подмножества.
  3. Используйте Apk Analyzer или DexCount, чтобы определить библиотеки, использующие наибольшее количество методов, и попытаться переместите их в отдельные функциональные модули.
  4. Прогард. Минификация должна быть в состоянии удалить неиспользуемые методы и помочь вам разместить базовый модуль в одном файле dex. Однако на данный момент Proguard довольно проблематичен с мгновенными приложениями. Вам нужно будет создать дополнительные правила proguard для каждого модуля.
person Tunca Ulubilge    schedule 16.11.2017