侧边栏壁纸
博主头像
Z同学博主等级

工作磨平激情前,坚持技术的热忱。 欢迎光临Z同学的技术小站。 分享最新的互联网知识。

  • 累计撰写 274 篇文章
  • 累计创建 55 个标签
  • 累计收到 74 条评论

Android Studio Maven编译与POM文档中 scope的差异

Z同学
2021-11-03 / 0 评论 / 3 点赞 / 626 阅读 / 2,569 字
温馨提示:
本文最后更新于 2021-11-18,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

说明

Android Studio 中提供了maven编辑工具。编译完成后可以生成POM文件。

但是不同的maven 工具编译后的pom 之中scope参数有差异。

例如apply plugin: 'maven-publish'apply plugin: 'maven'。这其实是两个maven插件。这两个maven插件生成的pom文件有部分区别。

而就因为这个区别,可能造成我们明明打包到pom上去了。 但是依赖的时候就是提示找不到相关aar文件。

本篇文章就是针对这个问题进行解释。

希望能够给小伙伴们提供一点帮助。

问题

我们有一个aar项目要编译,假如它叫做Zin.aar

我们的Zin.aar中有依赖很多其他库例如retrofit2的库等等。

我们将Zin.aar 集合到主App中的时候,我们不想在主App中重新添加一轮已经在Zin.aar 中添加依赖的库。

我们在dependencies 里面针对部分库 直接提供成 implementation。结果编译后在pom文件中implementation 标注的项目全部变成了。 <scope>runtime</scope>

而runtime 在主项目中编译开发的时候,无法引用。

但是你如果使用apply plugin: 'maven' 就不会出现这个问题。因为这个插件编译的pom文件中没有scope。

所以我们如果直接apply plugin: 'maven' 改为 apply plugin: 'maven-publish' 需要注意dependencies 里面的配置。否则会出现各种aar库找不到的问题。

详细说明

pom 文件说明

里面主要是这几个

   <dependency>
      <groupId>com.google.zxing</groupId> //groupId 组Id
      <artifactId>core</artifactId>       // 项目id 
      <version>3.3.0</version>            // 版本
       <scope>runtime</scope>            //作用域
    </dependency>

前面的 groupId ,artifactId ,version 这个如果有编译过maven就都知道这三个参数到底是什么意思。

这三个你可以当http网址上的域名地址来理解:类似 https://baseUrl/groupId/artifactId/version 然后找到一个文件夹。获取里面的maven项目源码而已。

关键是下面的第四个 scope :作用域。

scope 作用域

名字就已经告诉了我们它的作用了。 它就是表示该依赖库的使用范围。

我们如果使用apply plugin: 'maven' 进行编译。打包的pom文件中没有scope标签。没有的话,读取的时候就会使用默认值 compile。

  • compile : 默认值,标注这个库,不管是在编译还是运行阶段。都需要该库进行依赖。我们打包代码的时候,会将compile标准的库打包的项目源码中。也就是app中
  • test:测试,标注这个库只会参与测试调试阶段。我们如果打正式包的时候,不会打包进去。可以参考junit等。就是典型的test。
  • runntime:运行时编译。意思就是我们在编辑代码的时候,标准runntime的库你可能找不到。只有进行打包运行的时候,该依赖库就会被依赖进去。
  • provided:例外模式,就是该库我们在编辑代码的时候,可以引用。但是打包成运行项目后,不会将该库打包进去。会由运行平台自己提供这个库。由Android系统提供,我们app中不打包进去。
  • system:和provided差不多,但是该标注的maven是从本地系统里面拿,而不是从远程获取依赖库。这个依赖库也不会被运行代码给打包进去。---少见

总结:你依赖的库是平台提供的库,可以用provided,你如果是提供SDK 给他人做二次开发使用,建议compile。如果是测试就直接test。

针对不同scope我们配置dependencies

方法不全,我只是根据我的需求,列一下我配置的对应关系。

//方案1 
apply plugin: 'maven-publish'

dependencies {
    compile 'androidx.appcompat:appcompat:1.0.0'//将会打包到POM中,并标注compile  但是AS已经打算废弃这种写法了。
    implementation 'androidx.appcompat:appcompat:1.0.0'  // 标注implementation 的库将会打包成runntime
    compileOnly 'androidx.appcompat:appcompat:1.0.0'     //将不会打包到pom文件中。
    api 'androidx.appcompat:appcompat:1.0.0'  //将会打包到POM中,并标注compile 
    
}

//方案2 
apply plugin: 'maven'

dependencies {
    compile 'androidx.appcompat:appcompat:1.0.0'//将会打包到POM中
    implementation 'androidx.appcompat:appcompat:1.0.0'  // 将会打包到POM中
    compileOnly 'androidx.appcompat:appcompat:1.0.0'     //将不会打包到pom文件中。
    api 'androidx.appcompat:appcompat:1.0.0'  //将会打包到POM中
}

方案2打包的POM文件没有scope 标签,也就是说只要是打进去的,都是默认compile。要么有,要么无。

方案1是比较新的插件。建议大家还是尽量使用apply plugin: 'maven-publish'进行打包。这样更规范更符合标准。

如何使用maven进行打包,可以参考我的这篇文章:利用 Gitlab搭建 maven仓库 - Z同学 (zinyan.com)

以及这篇:Android Maven 打包不同的Flavors 的aar文件 - Z同学 (zinyan.com)

3

评论区