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

    После того как на 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
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 9

      0
      Даже страшно представить что отвалится в сборке приложений с использованием NDK / Experimental Gradle Plugin.
        0
        Не знал, что Jack уже выкинули. Что ж, да здравствует нормальная поддержка Java 8!
          0

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

            0

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


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

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

            • UFO just landed and posted this here
                +1
                С другой стороны, это защита от устаревшего legacy контента, который как гири на ногах с каждым годом все больше и больше создает проблем.
                0
                Использовать Android Studio Canary сборки, плохая идея. Слишком сырой продукт и как Вы написали без танцев с бубном не обошлось. Ждать только стабильную версию, особенно когда проект большой и не хочется чтобы в самый не подходящий момент все упало.
                Вообще ребята молодцы, движутся в правильном направлении. Правда не совсем понятен выход Android Studio 3.0 так как ещё 2.4 не вышел стабильный релиз, а они уже 3.0 выпускают.

                Only users with full accounts can post comments. Log in, please.