В чем разница между реализацией и компиляцией в Gradle?



после обновления до Android Studio 3.0 и создание нового проекта, я заметил, что в build.gradle есть новый способ добавить новые зависимости вместо compile здесь implementation и вместо testCompile здесь testImplementation.



пример:



 implementation 'com.android.support:appcompat-v7:25.0.0'
testImplementation 'junit:junit:4.12'


вместо



 compile 'com.android.support:appcompat-v7:25.0.0'
testCompile 'junit:junit:4.12'


в чем разница между ними и что я должен использовать?

2598   5  

5 ответов:

tl; dr

заменить:

  • compile С implementation
  • testCompile С testImplementation
  • debugCompile С debugImplementation
  • androidTestCompile С androidTestImplementation
  • compileOnly остается в силе. Он был добавлен в 3.0 для замены предоставленных и не компилируется. (provided введено, когда Gradle не имел имени конфигурации для этого прецедента и назвал его в честь предоставленного Maven масштаб.)

это один из прорывных изменений, поступающих с Gradle 3.0, что Google объявлено на IO17.

The compile конфигурация теперь устаревший и должен быть заменен на implementation или api

С Gradle documentation:

dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
}

зависимости, появляющиеся в api конфигурации будет транзитивное воздействие на потребителей библиотеки, и как таковой будет появится в пути к классам компиляции потребителей.

зависимости, найденные в implementation настройки в с другой стороны, не подвергаться воздействию потребителей, и поэтому не просачиваться внутрь путь к классу компиляции потребителей. Это имеет несколько преимуществ:

  • зависимости больше не просачиваются в путь к классам компиляции потребителей, поэтому вы никогда не будете случайно зависеть от транзитивного зависимость
  • быстрее компиляция благодаря уменьшенному размеру classpath
  • меньше перекомпиляций при изменении зависимостей реализации: потребители не должны быть перекомпилированы
  • cleaner publishing: при использовании в сочетании с новым плагином Maven-publish библиотеки Java создают файлы POM, которые точно различать, что требуется для компиляции против библиотека и что требуется для использования библиотеки во время выполнения (в другом слова, не смешивайте то, что необходимо для компиляции сама библиотека и какая необходимо скомпилировать против библиотеки).

конфигурация компиляции все еще существует, но не должна использоваться, поскольку она не будет предлагать гарантии того, что api и implementation конфигурации обеспечивают.


Примечание: если вы используете только библиотеку в вашем модуле приложения-общий случай-вы не заметите никакой разницы.
вы только увидите разницу, если у вас есть сложный проект с модулями, зависящими друг от друга, или вы создаете библиотеку.

этот ответ продемонстрирует разницу между implementation,api и compile о проекте. Допустим, у меня есть проект с тремя модулями Gradle:

  • приложение (Приложение для Android)
  • myandroidlibrary (библиотека Android)
  • myjavalibrary (библиотека Java)

app и myandroidlibrary в качестве зависимостей. myandroidlibrary и myjavalibrary в качестве зависимостей.

приложение -> myandroidlibrary -> myjavalibrary

myjavalibrary есть MySecret класс

public class MySecret {

    public static String getSecret() {
        return "Money";
    }
}

myandroidlibrary и MyAndroidComponent класс, который манипулирует значением из MySecret класса.

public class MyAndroidComponent {

    private static String component = MySecret.getSecret();

    public static String getComponent() {
        return "My component: " + component;
    }    
}

и наконец, app интересует только значение myandroidlibrary

TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());

теперь давайте поговорим о зависимости app построить.градля. Это очень просто и интуитивно понятно.

dependencies {
    implementation project(':myandroidlibrary')      
}

что думаете?myandroidlibrary построить.Gradle в должен выглядеть? У нас их три опции:

dependencies {
    // Option #1
    implementation project(':myjavalibrary') 
    // Option #2
    compile project(':myjavalibrary')      
    // Option #3
    api project(':myjavalibrary')           
}

в чем разница между ними и что я должен использовать?

компиляция и Api

если вы используете compile и api. Наше приложение для Android теперь может получить доступ myandroidcomponent зависимость, которая является MySecret класса.

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());

реализация

если вы используете implementation конфигурации MySecret не уязвимый.

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can NOT access MySecret
textView.setText(MySecret.getSecret()); // Won't even compile

Итак, какую конфигурацию вы выберите? Это действительно зависит от вашего требования.

если вы хотите выставить зависимости использовать api или compile, если вы не хотите выставлять зависимости (скрывая свой внутренний модуль), то используйте implementation.

это просто суть конфигураций Gradle, см. таблица 49.1. Плагин библиотеки Java-конфигурации, используемые для объявления зависимостей для получения более подробной объяснение.

пример проекта для этого ответа доступен на https://github.com/aldoKelvianto/ImplementationVsCompile

Compile конфигурация устарела и должна быть заменена implementation или api.

вы можете прочитать документы по адресу https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation.

краткая часть -

ключевая разница между стандартным плагином Java и Java Библиотечный плагин заключается в том, что последний вводит понятие API подвергается воздействию потребителей. Библиотека-это Java компонент, предназначенный быть потребляется другими компонентами. Это очень распространенный случай использования в мульти-проект строит, но и как только у вас есть внешний зависимости.

плагин предоставляет две конфигурации, которые могут быть использованы для объявления зависимости: api и реализация. Конфигурация api должна быть используется для объявления зависимостей, экспортируемых библиотекой API, в то время как конфигурация реализации должна использоваться для объявления зависимости, которые являются внутренними для деталь.

для дальнейшего объяснения обратитесь к этому изображению. Brief explanation

Краткое Решение:

лучший подход-заменить все compile зависимости implementation зависимостей. И только там, где вы пропускаете интерфейс модуля, вы должны использовать api. Это должно вызвать гораздо меньше перекомпиляции.

 dependencies {
         implementation fileTree(dir: 'libs', include: ['*.jar'])

         implementation 'com.android.support:appcompat-v7:25.4.0'
         implementation 'com.android.support.constraint:constraint-layout:1.0.2'
         // …

         testImplementation 'junit:junit:4.12'
         androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
             exclude group: 'com.android.support', module: 'support-annotations'
         })
 }

Объясню Подробнее:

перед Android Gradle плагин 3.0: у нас была большая проблема, которая заключается в том, что одно изменение кода вызывает перекомпиляцию всех модулей. Корень причина этого заключается в том, что Gradle не знает, пропускаете ли вы интерфейс модуля через другой или нет.

после Android Gradle плагин 3.0: последний плагин Android Gradle теперь требует, чтобы вы явно определили, если вы утечка интерфейса модуля. Исходя из этого он может сделать правильный выбор о том, что он должен перекомпилировать.

как compile зависимость устарела и заменена двумя новыми из них:

  • api: вы пропускаете интерфейс этого модуля через свой собственный интерфейс, что означает точно так же, как и старый compile зависимость

  • implementation: вы используете этот модуль только внутри и не пропускаете его через свой интерфейс

так что теперь вы можете явно сказать Gradle перекомпилировать модуль, если интерфейс используемого модуля изменяется или нет.

вежливость Йерун Молс блог

краткое различие в термине непрофессионала:

  • если вы работаете над интерфейсом или модулем, который обеспечивает поддержку других модулей, предоставляя элементы указанной зависимости, вы должны использовать "api".
  • если вы создаете приложение или модуль, который собирается реализовать или использовать указанную зависимость внутри, используйте "реализация".
  • 'compile' работал так же, как 'api', однако, если вы только реализуете или используете любая библиотека, "реализация" будет работать лучше и сэкономить ресурсы.

прочитайте ответ @aldok для всестороннего примера.

Comments

    Ничего не найдено.