С чем столкнулись при переводе проекта на Android Studio 3.0 Preview и Gradle 4.0-milestone-1

в 9:31, , рубрики: android, android studio 3.0, gradle 4.0, preview, разработка мобильных приложений, Разработка под android

После того как на Google IO 2017 Keynote анонсировали новую Android Studio 3.0 Preview и Gradle 4.0-milestone-1, конечно же, руки сразу чесались все это попробовать. Если в первой просто появилось много интересных фишечек, то во втором серьезно поменялось API.

Поэтому хотел бы коротко поделиться с чем столкнулся при переводе текущего приложения на эти новшества. Это не будет какой то обобщенный туториал или обзор всех плюшек. Это лишь пошаговый список проблем с которыми столкнулись лично мы в компании LiveTyping для одного конкретного проекта.

Сразу перечислим какие зависимости есть в проекте и с чем могли возникнуть проблемы:

  • apt
  • Retrolambda
  • RxJava2
  • Dagger2
  • Retrofit2
  • OkHttp3
  • ButterKnife
  • Moxy
  • StorIO
  • IcePick
  • AutoValue
  • GooglePlayServices
  • Calligraphy

Шаг 1.

Советую установить Android Studio 3.0 Preview рядом со старой Android Studio 2.3, а не вместо нее. Был горький опыт, который быстро отучил обновляться из Canary канала. Мне посчастливилось быть одним из тех счастливчиков у которых при обновлении на Android Studio 2.2 Preview 1 студия начала рандомно крашиться и не сохранять последние 2-5 минут работы. Повторялось — не у всех, и не лечилось до Preview 6. Откат не помогал.

Шаг 2.

Запустив свой проект на новой студии мы сразу же увидим сообщение

image

Либо соглашаемся сразу, либо делаем все руками

В %PROJECT%/gradle/wrapper/gradle-wrapper.properties заменяем

distributionUrl=https://services.gradle.org/distributions/gradle-3.3-all.zip

на

distributionUrl=https://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip

В %PROJECT%/build.gradle заменем

buildscript {
   dependencies {
-       classpath 'com.android.tools.build:gradle:2.3.0'
   }
}

на

buildscript {
   dependencies {
+        classpath 'com.android.tools.build:gradle:3.0.0-alpha1'
   }
}

Но тут один есть нюансик. Android Studio пока сама не добавляет репозиторий для скачивания android gradle plugin 3.0.0-alpha1. Поэтому, в любом случае, придется сделать это руками. Добавляем в %PROJECT%/build.gradle

buildscript {
   repositories {
        maven {
+            url 'https://maven.google.com'
        }
}

Шаг 3.

После синхронизации проекта появилась новая ошибка

image

image

Это наш самописный таск, который переименовывал apk файлы в удобный нам формат.
Идем в инструкцию по миграции на новый android gradle plugin и в самом низу видим следующее

API change in variant output

Using the Variant API to manipulate variant outputs is broken with the new plugin. If you're using this API with the new plugin, you'll see the following error message:

Error:(41, 0) Not valid.
This build error occurs because variant-specific tasks are no longer created during the configuration stage. This results in the plugin not knowing all of its outputs up front, but it also means faster configuration times. As an alternative, we will introduce new APIs to provide similar functionality.

Что ж, пока деваться некуда — просто закомментируем весь таск и живем так. Ждем когда появится новое API.

Позднее мы увидим что теперь apk файлы кладутся не в %PROJECT%/app/build/outputs/apk/ как раньше, а для них создаются отдельные каталоги по buildtypes и flavors. В нашем случае это 2 каталога

%PROJECT%/app/build/outputs/apk/debug
%PROJECT%/app/build/outputs/apk/release

И в каждом из них лежат 2 файла:

app-debug.apk
output.json

Если с первым все ясно, то интересно содержимое второго файла

[
    {
        "outputType": {
            "type": "APK"
        },
        "apkInfo": {
            "type": "MAIN",
            "splits": [],
            "versionCode": 10000
        },
        "outputFile": {
            "path": <FULL_APK_PATH>
        },
        "properties": {
            "packageId": <YOUR_PACKAGE_NAME>,
            "split": ""
        }
    }
]

Отлично, его можно использовать автоматизации аплоада apk файла.

Шаг 4.

После очередной синхронизации проекта мы увидим следующее сообщение

image

Information:Gradle tasks [:app:generateDebugSources, :app:mockableAndroidJar, :app:generateDebugAndroidTestSources]

Warning:The Jack toolchain is deprecated and will not run. To enable support for Java 8 language features built into the plugin, remove 'jackOptions { ... }' from your build.gradle file, and add

android.compileOptions.sourceCompatibility 1.8
android.compileOptions.targetCompatibility 1.8

Future versions of the plugin will not support usage of 'jackOptions' in build.gradle.
To learn more, go to https://d.android.com/r/tools/java-8-support-message.html

Warning:One of the plugins you are using supports Java 8 language features. To try the support built into the Android plugin, remove the following from your build.gradle:
    apply plugin: 'me.tatarka.retrolambda'
To learn more, go to https://d.android.com/r/tools/java-8-support-message.html

Warning:One of the plugins you are using supports Java 8 language features. To try the support built into the Android plugin, remove the following from your build.gradle:
    apply plugin: 'me.tatarka.retrolambda'
To learn more, go to https://d.android.com/r/tools/java-8-support-message.html

В целом здесь мы видим 2 сообщения

a. The Jack toolchain is deprecated и требуется полностью избавиться от его упоминания.
Вспоминаем что это действительно так и удаляем jackOptions из файла %PROJECT%/app/build.gradle

android {
   defaultConfig {
-       jackOptions {
-           enabled false
-       }
   }
}

b. Новая Android Studio 2.4 Preview частично поддерживает Java8 и Retrolambda больше не нужна. В соответствии с рекомендациями по миграции удаляем ее из проекта.

В файле %PROJECT%/build.gradle

buildscript {
   dependencies {
-       classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
-       classpath 'me.tatarka:gradle-retrolambda:3.3.0'
-       // NOTE: Do not place your application dependencies here; they belong
-       // in the individual module build.gradle files
   }
-   // Exclude the lombok version that the android plugin depends on.
-   configurations.classpath.exclude group: 'com.android.tools.external.lombok'
}

В файле %PROJECT%/app/build.gradle

- apply plugin: 'me.tatarka.retrolambda'

Добавляем поддержку Java8, если ее еще не было

android {
   compileOptions {
+       sourceCompatibility JavaVersion.VERSION_1_8
+       targetCompatibility JavaVersion.VERSION_1_8
   }
}

Шаг 5.

В соответствии с новым Gradle API заменяем dependency configurations

compile -> implementation
provided -> compileOnly

ни и для пущего понимания

debugCompile -> debugImplementation
releaseCompile -> releaseImplementation
debugProvided -> debugCompileOnly
releaseProvided -> releaseCompileOnly
testCompile -> testImplementation
androidTestCompile -> androidTestImplementation

ну или как то там, в соответствии с вашими buildtypes и flavors.

Шаг 6.

Еще ранее в проекте мы уже заменили apt plugin на annotationProcessor. Удалили все упоминания android-apt в файле %PROJECT%/build.gradle

buildscript {
   dependencies {
-       classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
   }
}

И в файле %PROJECT%/app/build.gradle

-  apply plugin: 'com.neenbedankt.android-apt'

И заменили в зависимости

apt -> annotationProcessor

После чего вам потребуется пересмотреть репозитории соответствующих библиотек (таких как Dagger2, StorIO, AutoValue, Butterknife, Timber, Moxy и другие) и заменить адреса их зависимостей целиком. Однако тут мы столкнулись с одной нерешаемой проблемой с крайне полезной библиотекой IcePick, которая, к сожалению, не поддерживает annotationProcessor и Kotlin.

image

Однако ребята из Evernote сделали свою аналогичную библиотеку Android-State, SNAPSHOT версия которой отлично справляется и имеет API похожее на API IcePick.

repositories {
    jcenter()

    maven {
+        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}

dependencies {
+  implementation 'com.evernote:android-state:1.1.0-SNAPSHOT'
+  annotationProcessor 'com.evernote:android-state-processor:1.1.0-SNAPSHOT'
}

Шаг 7.

И уже в самом конце нас ждал еще один сюрприз

image

Сразу может показаться что какая-то проблема с multidex. На самом деле оказалось что проблема с используемым нами dexcount-gradle-plugin. На страничке плагина мы увидели сообщение:

NOTE: dexcount does not currently work with the new Android Build Tools as of 3.0.0-alpha1; it has removed APIs that we depend on and, while replacements have been promised, none have yet been provided.

Ну что ж, пока тоже комментируем использование этого плагина и ждем правок.

Итог

Это был последний пункт, после которого проект успешно завелся. Это достаточно частный случай, но может быть кому то поможет быстрей разобраться в их проблемах миграции. Пишите в комментариях собираетесь ли пробовать на новую студию и Gradle в ближайшее время или собираетесь ждать релиза. С какими проблемами столкнулись вы?

Полезные ссылки:

  1. Android Studio 3.0 Preview 1
  2. New android plugin migration
  3. Java8 support
  4. Java8 language features support update

Автор: cosic

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js