2016-12-28 2 views
6

Мое приложение имеет зависимости от двух библиотек. Оба они используют одну и ту же библиотеку: org.hamcrest: hamcrest-core ', но разные версии внутри.Как град разрешает конфликты, когда две зависимости имеют внутреннюю зависимость от одной и той же библиотеки, но с разными версиями в Android?

androidTestCompile 'junit:junit:4.12' //(Depends on version 1.3) 
androidTestCompile 'org.mockito:mockito-core:1.10.19' //(Depends on version 1.1) 

Поскольку оба зависимостей связаны с Android instrumentation tests, приложение строит успешно, и включает в себя более высокую версию в сборке - в данном случае версии 1.3.

Но если я использую одну библиотеку для основного приложения и другой библиотеки для Android тестов Instrumentation следующим образом:

compile 'junit:junit:4.12' 
androidTCompile 'org.mockito:mockito-core:1.10.19' 

Я получаю следующее сообщение об ошибке.

:app:prepareDebugAndroidTestDependencies 
Conflict with dependency 'org.hamcrest:hamcrest-core'. Resolved versions for app (1.3) and test app (1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details. 

FAILED 

FAILURE: Build failed with an exception. 

* What went wrong: 
Execution failed for task ':app:prepareDebugAndroidTestDependencies'. 
> Dependency Error. See console for details. 

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

При проведении контрольно-измерительных испытаний как основной APK, так и тестовый APK имеют один и тот же путь к классам. Gradle build не сработает, если основной APK и тестовый APK используют одну и ту же библиотеку (например, Guava), но в разных версиях. Если град не поймал это, ваше приложение может вести себя по-разному во время тестов и во время обычного запуска (включая сбой в одном из случаев).

Upto данный момент у меня нет никаких проблем, но у меня есть проблемы в следующих случаях:

1) В приведенной ниже декларации, только один главный APK создается потому, что местные модульные тесты работают на виртуальная машина, то почему это не в состоянии с тем же исключением конфликта

compile 'junit:junit:4.12' 
testCompile 'org.mockito:mockito-core:1.10.19' 

2) И если выше не удается, поэтому это также должно потерпеть неудачу. Но удивительно, что это прекрасно работает и строит отлично.

androidTestCompile 'junit:junit:4.12' 
testCompile 'org.mockito:mockito-core:1.10.19' 

Я не могу понять эту неоднозначную природу, с которой gradle решает зависимостей в Android.

ответ

0

Объяснение

Как я понимаю, testCompile зависимостей также применимы к androidTestCompile. В противном случае вам нужно будет включить junit дважды, один для testCompile и один для androidTestCompile. Учитывая это, ваши дела легко объясняются:

1) testCompile включает в себя androidTestCompile, поэтому этот случай, очевидно, совпадает с самым первым примером в вашем вопросе, поэтому имеет смысл для него потерпеть неудачу.

2) Здесь compile нигде не упоминается, поэтому у главной APK не будет никакой версии Hamcrest, поэтому не может быть конфликта между основными и тестовыми APK.

Решение

same page you cited также говорит:

Для того, чтобы построить успех, просто убедитесь, что оба пакета APK использовать ту же версию. Если ошибка связана с косвенной зависимостью (библиотекой, которую вы не указали в вашем build.gradle), просто добавьте зависимость для более новой версии к конфигурации («компиляция» или «androidTestCompile»), которая в ней нуждается. (...)

Так что для того, чтобы предотвратить конфликт между основной и тестированием APK, вы можете явно указать, какую версию вы хотите в тестовой зависимости, например, так:

compile 'junit:junit:4.12' 
androidTestCompile 'org.mockito:mockito-core:1.10.19' 
androidTestCompile 'org.hamcrest:hamcrest-core:1.3' 

Примечание:

Конечно, только очень редко у нас есть веская причина включить junit в основной APK. Этот факт не делает недействительным вопрос, потому что многие другие зависимости могут быть между основным и тестовым APK, отличным от junit, наиболее вероятными являются библиотеки поддержки.