После того как на 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
Поделиться с друзьями
-->

Комментарии (9)


  1. VioletGiraffe
    26.05.2017 15:40

    Даже страшно представить что отвалится в сборке приложений с использованием NDK / Experimental Gradle Plugin.


  1. fRoStBiT
    26.05.2017 18:35

    Не знал, что Jack уже выкинули. Что ж, да здравствует нормальная поддержка Java 8!


  1. jehy
    26.05.2017 20:13

    Окей, с проблемами понятно. А можете описать, какой профит получили с перехода? Конечно, я умею читать new features, но интересно, что именно вам показалось стоящим перехода.


    1. cosic
      27.05.2017 10:44

      Главным образом мы преследовали следующие 3 интереса:


      1. Gradle 4 — они каждый раз обещают более быстрые сборки. Но увы, надежда не оправдала себя ни на секунду.
      2. Избавиться от Retrolambda. Вы должны знать, что она генерирует доп методы (до 7 для 2.1.0 версии и 4 для 2.3.0). А если перескочить на Java8 лямбды, то только один. И действительно, в целом из проекта ушло -9к методов с внедрениями всех описанных плюшек.
      3. Ну и конечно — просто сделать это! Что бы быть в эпицентре разворачиваемых событий ))


  1. Yoto
    26.05.2017 20:13

    А зачем Вы используете dexcount-gradle-plugin? Он ведь теперь вшит в саму студию. Или с ней тоже какие-то проблемы?


    1. cosic
      27.05.2017 10:01

      Да, теперь можно посмотреть из студии через APK Analyzer. Но по мне это не очень удобно. Люблю собирать через command line. А также dexcount-gradle-plugin помогает на CI получить информацию при каждой сборке.


  1. musicriffstudio
    27.05.2017 10:34

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

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

    Какая! то бесполезная трата рабочего времени.


    1. rPman
      29.05.2017 20:34
      +1

      С другой стороны, это защита от устаревшего legacy контента, который как гири на ногах с каждым годом все больше и больше создает проблем.


  1. AndXor
    28.05.2017 14:01

    Использовать Android Studio Canary сборки, плохая идея. Слишком сырой продукт и как Вы написали без танцев с бубном не обошлось. Ждать только стабильную версию, особенно когда проект большой и не хочется чтобы в самый не подходящий момент все упало.
    Вообще ребята молодцы, движутся в правильном направлении. Правда не совсем понятен выход Android Studio 3.0 так как ещё 2.4 не вышел стабильный релиз, а они уже 3.0 выпускают.