阅读 437

Android Gradle 管理依赖包

[toc]

Android 开发常见的gradle 依赖包相关的问题有如下:

Android 开发常见 Gradle 问题

  1. 如何查看项目里面引入的某个依赖包,具体是由哪个三方库引入的?
    • 问题场景1,多版本依赖:项目里面某个库存在多个版本,导致编译冲突,如何查看某个版本的库是由谁引入的 ?
    • 问题场景2,相同版本重复依赖:相同的依赖包,被重复引入。某些第三方库提供时内部已经集成了部分依赖库,接入方在接入时,同时引入了该版本的库。
    • 解决参看:解决问题1
  2. gradle 下载慢问题如何解决?
  3. gradle 下载的依赖包存放位置在哪儿,如何手动管理?

1. 查看 Gradle 项目包依赖关系

命令总结

gradle :app:dependencies --configuration debugCompileClasspath > de.txt
复制代码

为了解决问题1, 我们需要知道如何查看项目里的依赖关系,可以通过gradle命令查看:

// 开发环境已经配置gradle环境变量时直接使用gradle,模块名替换成项目中的模块名如 app
gradle :模块名:dependencies > de.txt
复制代码

上述命令,将指定模块的依赖关系,输出到 de.txt文件中,若环境中没有配gradle环境变量,也可以使用项目里面的graldew ,效果是一样的:

// 若无法执行,可先给 graldew 加可执行权限:chmod +x gradlew
./graldew :模块名:dependencies > de.txt
复制代码

1.1 gradle :app:dependencies --configuration debugCompileClasspath

打开 de.txt,里面会根据不同的编译模式,输出相应的依赖关系,例如有:

debugAndroidTestCompileClasspath - Compile classpath for compilation 'debugAndroidTest' (target  (androidJvm)).
debugCompileClasspath - Compile classpath for compilation 'debug' (target  (androidJvm)).
debugUnitTestCompileClasspath - Compile classpath for compilation 'debugUnitTest' (target  (androidJvm)).
releaseCompileClasspath - Compile classpath for compilation 'release' (target  (androidJvm)).
releaseUnitTestCompileClasspath - Compile classpath for compilation 'releaseUnitTest' (target  (androidJvm)).
...
复制代码

这里,我们重点关注 debugCompileClasspath(即 debug下的依赖关系) 与 releaseCompileClasspath(即 release下的依赖关系)。 我们还可以通过加过滤参数 --configuration 编译模式 ,只关注对应编译模式下的依赖关系,例如:

gradle :app:dependencies --configuration debugCompileClasspath > de.txt
复制代码
  1. app module 的build.gradle如下
     implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
     implementation "androidx.core:core-ktx:${androidx_core_ktx}"
     implementation "androidx.appcompat:appcompat:${androidx_appcompat}"
     implementation "androidx.constraintlayout:constraintlayout:${androidx_constraintlayout}"
     implementation "com.google.android.material:material:${material}"
     implementation "com.alibaba:arouter-api:${arouter}"
     annotationProcessor "com.alibaba:arouter-compiler:${arouter}"
     kapt "com.alibaba:arouter-compiler:${arouter}"
     implementation project(":lib_order")
     implementation project(":lib_pay")
    复制代码
  2. 得到的依赖结果以 debugCompileClasspath 为例,如下:
     debugCompileClasspath - Compile classpath for compilation 'debug' (target  (androidJvm)).
     +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.72
     |    +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72
     |    \--- org.jetbrains:annotations:13.0
     +--- androidx.core:core-ktx:1.3.2
     |    +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.71 -> 1.3.72 (*)
     |    +--- androidx.annotation:annotation:1.1.0
     |    \--- androidx.core:core:1.3.2
     |         +--- androidx.annotation:annotation:1.1.0
     |         +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.1.0
     |         |    +--- androidx.lifecycle:lifecycle-common:2.1.0
     |         |    |    \--- androidx.annotation:annotation:1.1.0
     |         |    +--- androidx.arch.core:core-common:2.1.0
     |         |    |    \--- androidx.annotation:annotation:1.1.0
     |         |    \--- androidx.annotation:annotation:1.1.0
     |         \--- androidx.versionedparcelable:versionedparcelable:1.1.0
     |              +--- androidx.annotation:annotation:1.1.0
     |              \--- androidx.collection:collection:1.0.0 -> 1.1.0
     |                   \--- androidx.annotation:annotation:1.1.0
     +--- androidx.appcompat:appcompat:1.2.0
     |    +--- androidx.annotation:annotation:1.1.0
     |    +--- androidx.core:core:1.3.0 -> 1.3.2 (*)
     |    +--- androidx.cursoradapter:cursoradapter:1.0.0
     |    |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    +--- androidx.fragment:fragment:1.1.0
     |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |    |    +--- androidx.collection:collection:1.1.0 (*)
     |    |    +--- androidx.viewpager:viewpager:1.0.0
     |    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |    |    +--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |    |    |    \--- androidx.customview:customview:1.0.0
     |    |    |         +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |    |         \--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |    |    +--- androidx.loader:loader:1.0.0
     |    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |    |    +--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |    |    |    +--- androidx.lifecycle:lifecycle-livedata:2.0.0
     |    |    |    |    +--- androidx.arch.core:core-runtime:2.0.0
     |    |    |    |    |    +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |    |    |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
     |    |    |    |    +--- androidx.lifecycle:lifecycle-livedata-core:2.0.0
     |    |    |    |    |    +--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.1.0 (*)
     |    |    |    |    |    +--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
     |    |    |    |    |    \--- androidx.arch.core:core-runtime:2.0.0 (*)
     |    |    |    |    \--- androidx.arch.core:core-common:2.0.0 -> 2.1.0 (*)
     |    |    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0
     |    |    |         \--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.activity:activity:1.0.0
     |    |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    |    +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |    |    |    +--- androidx.lifecycle:lifecycle-runtime:2.1.0 (*)
     |    |    |    +--- androidx.lifecycle:lifecycle-viewmodel:2.1.0 (*)
     |    |    |    \--- androidx.savedstate:savedstate:1.0.0
     |    |    |         +--- androidx.annotation:annotation:1.1.0
     |    |    |         +--- androidx.arch.core:core-common:2.0.1 -> 2.1.0 (*)
     |    |    |         \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.1.0 (*)
     |    |    \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.1.0 (*)
     |    +--- androidx.appcompat:appcompat-resources:1.2.0
     |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.core:core:1.0.1 -> 1.3.2 (*)
     |    |    +--- androidx.vectordrawable:vectordrawable:1.1.0
     |    |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    |    +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |    |    |    \--- androidx.collection:collection:1.1.0 (*)
     |    |    \--- androidx.vectordrawable:vectordrawable-animated:1.1.0
     |    |         +--- androidx.vectordrawable:vectordrawable:1.1.0 (*)
     |    |         +--- androidx.interpolator:interpolator:1.0.0
     |    |         |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |         \--- androidx.collection:collection:1.1.0 (*)
     |    \--- androidx.drawerlayout:drawerlayout:1.0.0
     |         +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |         +--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |         \--- androidx.customview:customview:1.0.0 (*)
     +--- androidx.constraintlayout:constraintlayout:2.0.4
     |    +--- androidx.appcompat:appcompat:1.2.0 (*)
     |    +--- androidx.core:core:1.3.1 -> 1.3.2 (*)
     |    \--- androidx.constraintlayout:constraintlayout-solver:2.0.4
     +--- com.google.android.material:material:1.3.0
     |    +--- androidx.annotation:annotation:1.0.1 -> 1.1.0
     |    +--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*)
     |    +--- androidx.cardview:cardview:1.0.0
     |    |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    +--- androidx.coordinatorlayout:coordinatorlayout:1.1.0
     |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |    |    +--- androidx.customview:customview:1.0.0 (*)
     |    |    \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)
     |    +--- androidx.constraintlayout:constraintlayout:2.0.1 -> 2.0.4 (*)
     |    +--- androidx.core:core:1.2.0 -> 1.3.2 (*)
     |    +--- androidx.dynamicanimation:dynamicanimation:1.0.0
     |    |    +--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |    |    +--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)
     |    |    \--- androidx.legacy:legacy-support-core-utils:1.0.0
     |    |         +--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |         +--- androidx.core:core:1.0.0 -> 1.3.2 (*)
     |    |         +--- androidx.documentfile:documentfile:1.0.0
     |    |         |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |         +--- androidx.loader:loader:1.0.0 (*)
     |    |         +--- androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
     |    |         |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    |         \--- androidx.print:print:1.0.0
     |    |              \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
     |    +--- androidx.annotation:annotation-experimental:1.0.0
     |    +--- androidx.fragment:fragment:1.0.0 -> 1.1.0 (*)
     |    +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.1.0 (*)
     |    +--- androidx.recyclerview:recyclerview:1.0.0 -> 1.1.0
     |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |    |    +--- androidx.customview:customview:1.0.0 (*)
     |    |    \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)
     |    +--- androidx.transition:transition:1.2.0
     |    |    +--- androidx.annotation:annotation:1.1.0
     |    |    +--- androidx.core:core:1.0.1 -> 1.3.2 (*)
     |    |    \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*)
     |    +--- androidx.vectordrawable:vectordrawable:1.1.0 (*)
     |    \--- androidx.viewpager2:viewpager2:1.0.0
     |         +--- androidx.annotation:annotation:1.1.0
     |         +--- androidx.fragment:fragment:1.1.0 (*)
     |         +--- androidx.recyclerview:recyclerview:1.1.0 (*)
     |         +--- androidx.core:core:1.1.0 -> 1.3.2 (*)
     |         \--- androidx.collection:collection:1.1.0 (*)
     +--- com.alibaba:arouter-api:1.5.1
     |    \--- com.alibaba:arouter-annotation:1.0.6
     +--- project :lib_order
     +--- project :lib_pay
     +--- org.jetbrains.kotlin:kotlin-stdlib:{strictly 1.3.72} -> 1.3.72 (c)
     +--- androidx.core:core-ktx:{strictly 1.3.2} -> 1.3.2 (c)
     +--- androidx.appcompat:appcompat:{strictly 1.2.0} -> 1.2.0 (c)
     +--- androidx.constraintlayout:constraintlayout:{strictly 2.0.4} -> 2.0.4 (c)
     +--- com.google.android.material:material:{strictly 1.3.0} -> 1.3.0 (c)
     +--- com.alibaba:arouter-api:{strictly 1.5.1} -> 1.5.1 (c)
     +--- org.jetbrains.kotlin:kotlin-stdlib-common:{strictly 1.3.72} -> 1.3.72 (c)
     +--- org.jetbrains:annotations:{strictly 13.0} -> 13.0 (c)
     +--- androidx.annotation:annotation:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.core:core:{strictly 1.3.2} -> 1.3.2 (c)
     +--- androidx.cursoradapter:cursoradapter:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.fragment:fragment:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.appcompat:appcompat-resources:{strictly 1.2.0} -> 1.2.0 (c)
     +--- androidx.drawerlayout:drawerlayout:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.constraintlayout:constraintlayout-solver:{strictly 2.0.4} -> 2.0.4 (c)
     +--- androidx.cardview:cardview:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.coordinatorlayout:coordinatorlayout:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.dynamicanimation:dynamicanimation:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.annotation:annotation-experimental:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.lifecycle:lifecycle-runtime:{strictly 2.1.0} -> 2.1.0 (c)
     +--- androidx.recyclerview:recyclerview:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.transition:transition:{strictly 1.2.0} -> 1.2.0 (c)
     +--- androidx.vectordrawable:vectordrawable:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.viewpager2:viewpager2:{strictly 1.0.0} -> 1.0.0 (c)
     +--- com.alibaba:arouter-annotation:{strictly 1.0.6} -> 1.0.6 (c)
     +--- androidx.versionedparcelable:versionedparcelable:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.collection:collection:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.viewpager:viewpager:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.loader:loader:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.activity:activity:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.lifecycle:lifecycle-viewmodel:{strictly 2.1.0} -> 2.1.0 (c)
     +--- androidx.vectordrawable:vectordrawable-animated:{strictly 1.1.0} -> 1.1.0 (c)
     +--- androidx.customview:customview:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.legacy:legacy-support-core-utils:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.lifecycle:lifecycle-common:{strictly 2.1.0} -> 2.1.0 (c)
     +--- androidx.arch.core:core-common:{strictly 2.1.0} -> 2.1.0 (c)
     +--- androidx.lifecycle:lifecycle-livedata:{strictly 2.0.0} -> 2.0.0 (c)
     +--- androidx.savedstate:savedstate:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.interpolator:interpolator:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.documentfile:documentfile:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.localbroadcastmanager:localbroadcastmanager:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.print:print:{strictly 1.0.0} -> 1.0.0 (c)
     +--- androidx.arch.core:core-runtime:{strictly 2.0.0} -> 2.0.0 (c)
     \--- androidx.lifecycle:lifecycle-livedata-core:{strictly 2.0.0} -> 2.0.0 (c)
    复制代码

通过上述依赖关系结构结果,我们找到需要关注的依赖包,以及最终依赖包的版本,即可解决依赖冲突、重复引入依赖包等问题。

1.2 Gradle 3种编译依赖模式 implementation、compileOnly、api 与问题

假设我们写了一个 lib module:myLib,依赖了 okhttp3库,我们有3种依赖 okhttp3 库的方式

  1. implementation
    • 内部使用 声明式依赖,不传递依赖关系,只在模块内部使用被依赖的 okhttp3 api,接入方无需再次引入 okhttp3;
    • 若接入方也声明依赖了 okhttp3 版本,gradle 将自动使用最高版本进行项目编译
  2. compileOnly
    • 参与编译 声明式依赖,同 implementation ,与其唯一区别,接入方在使用 myLib 时,必须引入被依赖的库,即声明 implementation "com.squareup.okhttp3:okhttp:${okhttp3}",否则报错
  3. api
    • 打包依赖,会传递依赖关系,相关api,会直接打包进入输出sdk中。
    • implementationcompileOnly 都只是声明依赖,不会将被依赖对象打包输出到编译产物中。

使用场景

  • api: 一般在项目分层中的较底层使用,暴露底层接口给上层,上层不需要重复声明依赖底层库
  • compileOnly:一般用于 sdk 设计时,需要用到第三方库,而又不想集成到到sdk中输出,同时接入时,强制要求接入方必须显示接入该sdk 中依赖的库才可正常使用
  • implementation:一般除上述场景:应用的app module、sdk设计输出无需接入方显示引入内部依赖库等。

1.3 关于重复依赖与多版本依赖

+--- androidx.appcompat:appcompat:1.2.0
|    +--- androidx.annotation:annotation:1.1.0
|    +--- androidx.core:core:1.3.0 -> 1.3.2 (*)
|    +--- androidx.cursoradapter:cursoradapter:1.0.0
|    |    \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
...
复制代码

上述含义:appcompat: 1.2.0 编译,依赖 annotation:1.1.0、core:1.3.0、cursoradapter:1.0.0、...包 而 cursoradapter:1.0.0 编译又依赖 annotation:1.0.0 , 这时 gradle 自动将使用高版本 annotation:1.1.0 。

  • 通过声明依赖的方式,gradle会自动处理重复依赖问题,并且对于同一个库的不同版本,gradle会自动使用最新版本来进行依赖替换、编译
  • 而如果是sdk 库再输出的时候,用的是打包依赖,即 api 方式,则会在输出时,内置依赖的第三方库,gradle无法再自动使用最新版本来处理,照成依赖冲突问题

1.4 exclude 排除三方库中引入的依赖包

exclude 排除三方库中引入的依赖包主要用法有以下两种,根据实际情况,使用一种即可

  implementation ("groupName:moduleName:XXX") {
//    exclude group: 'com.android.support'
    exclude group: 'com.android.support', module: 'support-compat'
}
复制代码

1.5 解决问题1

回答文章开头的问题1, 要解决主要有两种思路。

  1. sdk 输出方,设计原则
    • 尽量避免内部集成第三方库输出,即不要采用 api 方式 或者 直接 include jar 方式,而要使用compileOnlyimplementation 声明依赖的方式,去依赖第三方库
  2. sdk 接入方,接入原则
    • 接入sdk时,遇到依赖冲突问题,先查看依赖关系:gradle :app:dependencies --configuration debugCompileClasspath > de.txt,找到引入冲突包的引入点,在其上 exclude 掉重复引入的库。

2. gradle 下载慢问题

使用aliyun maven 镜像即可解决部分依赖库下载慢问题,具体配置参考官方网站。 配置思路有两种:全局配置当前工程配置。 官方主要是对当前工程进行配置生效,我们若有需要对所有工程生效,还可将官方配置文件,放到用户的gradle 目录,MAC 下即 cd ~/.gradle, 新建init.gradle,放置上述配置内容即可。

3. gradle cache 目录结构

3.1 gradle顶级目录

gradle 本身路径:UserHome/.gradle,其目录下有:

  1. caches:gradle缓存目录
  2. daemon: daemon日志目录
  3. native: gradle平台相关目录
  4. wrapper:gradle-wrapper下载目录

3.2 caches 目录

caches 本身路径:UserHome/.gradle/caches,其目录下有:

  1. 2.14.1::gradle程序的脚本(gradle程序版本)

...

  1. 6.6.1:gradle程序的脚本(gradle程序版本)
  2. jars-2
  3. jars-3
  4. jars-8
  5. journal-1
  6. modules-2 : 下载缓存目录
  7. transforms-1
  8. transforms-2

3.3 caches/modules-2 目录

modules-2 本身路径:UserHome/.gradle/caches/modules-2,其目录下有: files-2.1:gradle下载的jar/aar目录

3.4 files-2.1的目录组织(jar/aar都下载到这里)

files-2.1本身路径:UserHome/.gradle/caches/modules-2/files-2.1,其目录下有:

${org}/${package}/${version}/${shanum1}/${package-version}.pom
${org}/${package}/${version}/${shanum2}/${package-version}.jar
${org}/${package}/${version}/${shanum3}/${package-version}-sources.jar
${org}/${package}/${version}/${shanum4}/${package-version}-javadoc.jar  
复制代码

3.5 手动下载依赖库 (aar/jar) 替换gradle cache 缓存

下面以okhttp3为例,如何手动下载该依赖包,替换到gradle cache中

  1. 访问okhttp3 指定版本maven仓库:repo1.maven.org/maven2/com/…

    okhttp-3.10.0-javadoc.jar                         2018-02-24 18:35    352538      
    okhttp-3.10.0-javadoc.jar.asc                     2018-02-24 18:35       833      
    okhttp-3.10.0-javadoc.jar.md5                     2018-02-24 18:35        32      
    okhttp-3.10.0-javadoc.jar.sha1                    2018-02-24 18:35        40      
    okhttp-3.10.0-sources.jar                         2018-02-24 18:35    314424      
    okhttp-3.10.0-sources.jar.asc                     2018-02-24 18:35       833      
    okhttp-3.10.0-sources.jar.md5                     2018-02-24 18:35        32      
    okhttp-3.10.0-sources.jar.sha1                    2018-02-24 18:35        40      
    okhttp-3.10.0.jar                                 2018-02-24 18:35    412117      
    okhttp-3.10.0.jar.asc                             2018-02-24 18:35       833      
    okhttp-3.10.0.jar.md5                             2018-02-24 18:35        32      
    okhttp-3.10.0.jar.sha1                            2018-02-24 18:35        40      
    okhttp-3.10.0.pom                                 2018-02-24 18:35      2302      
    okhttp-3.10.0.pom.asc                             2018-02-24 18:35       833      
    okhttp-3.10.0.pom.md5                             2018-02-24 18:35        32      
    okhttp-3.10.0.pom.sha1                            2018-02-24 18:35        40      
    复制代码
  2. 访问其中的 okhttp-3.10.0.jar.sha1 ,获取 jar 包的 sha1 值为:7ef0f1d95bf4c0b3ba30bbae25e0e562b05cf75e

  3. sha1 值 7ef0f1d95bf4c0b3ba30bbae25e0e562b05cf75e,在本地新建文件夹:UserHome/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/3.10.0/7ef0f1d95bf4c0b3ba30bbae25e0e562b05cf75e

  4. 下载其中的 okhttp-3.10.0.jar 文件,放入上述文件夹中

  5. 如果还需要其他文件: okhttp-3.10.0.pomokhttp-3.10.0-sources.jarokhttp-3.10.0-javadoc.jar,重复上述步骤即可。 总结:先获取到对应文件的 sha1值,以该值创建文件夹,再将下载的文件放入创建的文件夹中。

4. Gradle 编译输出 aar

// 执行指令后,查看目录:build/outputs/aar/
gradle assemble
复制代码
文章分类
Android
文章标签