Android应用开发之Android - Understanding and dominating gradle dependencies
白羽 2018-12-19 来源 :网络 阅读 395 评论 0

摘要:本文将带你了解Android应用开发Android - Understanding and dominating gradle dependencies,希望本文对大家学Android有所帮助。

    本文将带你了解Android应用开发Android - Understanding and dominating gradle dependencies,希望本文对大家学Android有所帮助。



        

Android - Understanding and dominating gradle dependencies

From

https://www.devsbedevin.com/android-understanding-gradle-dependencies-and-resolving-conflicts/

My latest post discussed gradle'sdependencyInsighttask. let's pe deeper into dependencies, direct and transitive, and gradle's dependency tools.

Direct VS. Transitive

Transitive dependency is an implied dependency, allowing your project to depend on libraries that depend on other libraries. The result is a dependency tree. These trees tend to get complex as your project requires more and more libraries to compile.
A direct, or "first level" dependency is one that you the developer explicitly import.

Exploring the dependency tree

We'll get back to transitive dependencies in a second. For now let's look at a project's entire dependency tree.
Invokinggradle dependencies --configuration compileresults in something like this:

Already we can learn that this project has a lot of dependency conflicts. Those are marked by
{library name}:{required version} -> {actual version}

Conflicts

It is very common for for different modules and libraries to share the same dependencies. Who doesn't useapache-commonsandGSon Huh folks Am I right This guy knows what I'm talking about.

A problem arises when the dependency is the same, but each module or library expects a different version. This causes the project to contain multiple versions of the same class, and in turn causes the Dex tool to fail with the following error:

 

com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry:

Resolving conflicts

If we didn't have gradle's transient dependency management, we would have to manually keep track of each dependency and resolve version conflicts by hand. This becomes harder the larger your project is. Lucky us we have gradle to handle the headache in one of several ways:

The default behaviour is to settle on the newest version of the requested dependency. Please mind the wordnewestas opposed tohighest version requested. This is fine as long as the versions are backward compatible with the lowest version your project expects.

Second most popular resolution is to fail the build. You, the developer, would have to resolve the conflicts yourself.

Configuring a first level dependency as forced is useful in cases where the conflicted transient dependency is already a direct (=first level) dependency.

You may also configure a transient dependency as forced, thus forcing your entire project to settle on a specific version.

If your build contains custom forks of the conflicted dependency, you may force gradle to use your own modules.

You may tell gradle to not resolve transient dependencies of a specific library at all. Of course you would need to rely instead on manually added direct dependencies and/or existing transient ones.

You may as well exclude specific transient dependencies referenced by a direct one.

Configuring build.gradle

The aforementioned strategies do not always translate directly to configuration switches.
Let's go over the basic techniques in achieving what we want:

Controlling dependencies project wide

This is achieved via theresolutionStrategyartifact.

 Failing on version conflict

Add the following to your main project'sbuild.gradlefile.


   

configurations.all {

  resolutionStrategy {

 failOnVersionConflict()

  }

}

   

 Forcing a specific dependency

The following example forcesasm-all 3.3.1,commomns-io 1.4, and latestboltswhere the major version number is 1 (i.e. bolts 1.x):


   

configurations.all {

  resolutionStrategy {

 force 'asm:asm-all:3.3.1', 'commons-io:commons-io:1.4', 'com.parse.bolts:bolts-android:1.+'

  }

}

   

 Preferring own modules

Always prefer own modules:


   

configurations.all {

  resolutionStrategy {

 preferProjectModules()

  }

}

   

Replace all instances ofcommons-iowith a custom modulemy-commons-io:


   

configurations.all {

  resolutionStrategy {

 dependencySubstitution {

substitute module('commons-io:commons-io:2.4') with project(':my-commons-io')

 }

  }

}

   

Controlling specific dependencies

You may also fine grain your settings to a specific dependency on a specific project.

 Excluding transient dependencies

Adding this to your dependencies tag would add the libraryappcompat-v7but none of its own transient dependencies. You will have to make sure that all of the libraries needed dependencies are added either by adding direct dependencies yourself or by relying on transient dependencies referenced by other modules:


   

dependencies {

 compile('com.android.support:appcompat-v7:23.1.0') {

  transitive = false

 }

}

   

The default fortransitiveistrue.

You can also exclude specific transient dependencies. The following example excludes theboltslibrary from being added, if needed byappcompat:


   

dependencies {

 compile('com.android.support:appcompat-v7:23.1.0') {

  exclude group: 'com.parse.bolts'

 }

}

   

 Forcing a specific version

This forces your project to settle onboltsversion 1.1:



   

dependencies {

 compile('com.parse.bolts:bolts-android:1.+') {

  force = true

 }

}

   

TL;DR

Controlling dependencies project wide

Example taken from gradle'sofficial docs:



   

configurations.all {

  resolutionStrategy {

 // fail eagerly on version conflict (includes transitive dependencies)

 // e.g. multiple different versions of the same dependency (group and name are equal)

 failOnVersionConflict()

 

 // prefer modules that are part of this build (multi-project or composite build) over external modules

 preferProjectModules()

 

 // force certain versions of dependencies (including transitive)

 //  *append new forced modules:

 force 'asm:asm-all:3.3.1', 'commons-io:commons-io:1.4'

 //  *replace existing forced modules with new ones:

 forcedModules = ['asm:asm-all:3.3.1']

 

 // add dependency substitution rules

 dependencySubstitution {

substitute module('org.gradle:api') with project(':api')

substitute project(':util') with module('org.gradle:util:3.0')

 }

 

 // cache dynamic versions for 10 minutes

 cacheDynamicVersionsFor 10*60, 'seconds'

 // don't cache changing modules at all

 cacheChangingModulesFor 0, 'seconds'

  }

}

   

Controlling specific dependencies


   

dependencies {

 

 // We load commons-io but none of its transient dependencies

 compile('commons-io:commons-io:2.4') {

  transitive = false

 }

 

 // We exclude bolts altogether from appcompat's transient dependencies

 compile('com.android.support:appcompat-v7:23.1.0') {

  exclude group: 'com.parse.bolts'

 }

 

 // Force a specific version

 compile('com.parse.bolts:bolts-android:1.+') {

  force = true

 }

}

   

Exploring dependencies

To review all of your project's dependencies:
gradle dependencies --configuration CONFIGURATION_NAME

To inspect a specific dependency (more on this inthis post):
gradle -q dependencyInsight --configuration CONFIGURATION_NAME --dependency DEPENDENCY_NAME

          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程