В чем разница между реализацией и компиляцией в 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'
в чем разница между ними и что я должен использовать?
5 ответов:
tl; dr
заменить:
compileСimplementationtestCompileСtestImplementationdebugCompileСdebugImplementationandroidTestCompileСandroidTestImplementationcompileOnlyостается в силе. Он был добавлен в 3.0 для замены предоставленных и не компилируется. (providedвведено, когда Gradle не имел имени конфигурации для этого прецедента и назвал его в честь предоставленного Maven масштаб.)это один из прорывных изменений, поступающих с Gradle 3.0, что Google объявлено на IO17.
The
compileконфигурация теперь устаревший и должен быть заменен наimplementationилиapidependencies { 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интересует только значениеmyandroidlibraryTextView 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, в то время как конфигурация реализации должна использоваться для объявления зависимости, которые являются внутренними для деталь.
Краткое Решение:
лучший подход-заменить все
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