在Android项目上启用maven

一、

眼下Android的开发正如火如荼,开发方式大多数是Android SDK+Eclipse+ADT,大部分的操作都要依赖Eclipse(当然有高手直接敲命令的)。如果项目依赖其它库资源在不同的机器上难免又要设置一番,而且库资源及其依赖管理是相当混乱,针对这种情况,Maven是一个很好的解决方案,下面讲叙述如何将Android的工程与Maven整合。

首先介绍一下需要用到的工具:

Android SDK——这个不用说了,必须的

Eclipse——同上

Android Development Tool(ADT)——相信绝大部分的人都依赖这个插件来开发Android项目的

以上是搭建一个Android项目的基本需要,下面是整合Maven需要的一些工具(插件)

Maven Eclipse Plugin(m2e)——用过Maven的一般都熟悉这个,这个是一个Eclipse的插件,其具有如下功能:

  1. 识别工程内的pom.xml,并使用独有的编辑器打开pom.xml
  2. 将pom.xml内部声明的依赖库添加至“Maven Dependencies”的Library Container,这个是使我们能在EclipseIDE内使用pom.xml内声明的库的主要原因
  3. 在java builder内加入maven的builder,使从eclipse内执行时能够使用到maven相关功能
  4. 增加maven的各种独有的运行设置
Android Development Tools and the M2Eclipse——这个是Eclipse的插件,充当的角色是ADT及m2e之间的桥梁,由于Android项目的特性,Maven所做的操作在Android的项目上并不适用,所以这个插件相当于两个插件之间的适配器,使得m2e的插件作出的变更及其通知能够以ADT所能接受的方式通知ADT对Android的项目作出响应的变更。
Android Maven Plugin——这个是Maven的插件,目的是能在使用mvn package时让maven构建出一个能在Android上使用的目标文件。

工具的介绍完毕,下面看看如何将Maven整合进一个Android工程:
首先看看对于已经存在的Android工程:
  1. 安装好如上的插件,在Android的工程上点右键,弹出菜单Configure->Convert to Maven project
  2. 配置好项目信息后会生成pom.xml以及工程上的图标已经多出一个小M字

  3. 更改project的packaging类型为apk
    [html]  view plain copy
    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
    3.     <modelVersion>4.0.0</modelVersion>  
    4.   
    5.     <groupId>org.cst.ming.android.sample</groupId>  
    6.     <artifactId>sample</artifactId>  
    7.     <version>0.0.1-SNAPSHOT</version>  
    8.     <packaging>apk</packaging>  
    9. ......  
  4. 在pom内声明一个build的插件,在maven构建项目的时候就会在target内生成一个apk的文件
    [html]  view plain copy
    1. <plugin>  
    2.     <groupId>com.jayway.maven.plugins.android.generation2</groupId>  
    3.     <artifactId>android-maven-plugin</artifactId>  
    4.     <version>3.0.0</version>  
    5.     <inherited>true</inherited>  
    6.     <extensions>true</extensions>  
    7.     <configuration>  
    8.         <sdk>  
    9.             <platform>7</platform>  
    10.             <path>${env.ANDROID_SDK_HOME}</path>  
    11.         </sdk>  
    12.         <deleteConflictingFiles>true</deleteConflictingFiles>  
    13.         <undeployBeforeDeploy>true</undeployBeforeDeploy>  
    14.     </configuration>  
    15. </plugin>  
    注意,这里指定了插件的版本,这个是maven官方提供的建议,需要在构建插件中指定插件版本;还有一点就是必须指定sdk.platform及sdk.path属性,不然会因为找不到sdk而无法build的
  5. 这时候可以在pom.xml内添加各种的依赖,并且执行mvn clean package即可构建出一个apk文件在target
  6. 此时已经整合完毕,可以在IDE内通过ADT来启动项目,亦可以通过在pom.xml内配置android-maven-plugin通过mvn android:deploy将项目部署到指定的设备(虚拟机)上,详情可以查阅android-maven-plugin的官方文档
对于新建项目的:
在新建项目的时候可以采用archetype(项目原型)的方式构建,在向导内选择项目原型,分别有
de.akquinet.android.archetypes:android-quickstart:1.0.6——用于快速构建一个android-maven项目
de.akquinet.android.archetypes:android-with-test:1.0.6——用于构建一个带有测试的android-maven项目
de.akquinet.android.archetypes:android-release:1.0.6——用于构建一个可以发布的android-maven项目,其中包含了一个纯maven的父项目及两个子android-maven项目
在项目创建之后,还有点需要修改的,由于android-maven-plugin原名为maven-android-plugin,因为某种关系在某个版本之后更名为android-maven-plugin,但在这个原型内还是使用旧的maven-android-plugin,所以需要使用新插件的必须手动修改plugin.artifactId及其plugin.version


刚才正在配置一个项目的报告输出,在配置pom的时候按照maven2的做法在<reporting>节点下加上了pmd、checkstyle等plugin

[html]  view plain copy
  1. <reporting>  
  2.   <plugins>  
  3.     <plugin>  
  4.       <groupId>org.apache.maven.plugins</groupId>  
  5.       <artifactId>maven-checkstyle-plugin</artifactId>  
  6.       <version>${checkstyle.plugin.version}</version>  
  7.     </plugin>  
  8.     <plugin>  
  9.       <groupId>org.apache.maven.plugins</groupId>  
  10.       <artifactId>maven-pmd-plugin</artifactId>  
  11.       <version>${pmd.plugin.version}</version>  
  12.     </plugin>  
  13. </reporting>  

却发现在target/site目录下除了image及css文件夹之外,一个html也没有,而且预期的报告也没有生成,我就纳闷了

几经Google后,终于查到,原来maven-site-plugin在3.0版本采用了一种全新的配置形式,导致不能接受<reporting>节点下声明的报告插件,这一点在其官方网站上有介绍:http://maven.apache.org/plugins/maven-site-plugin/maven-3.html#Configuration_formats

解决办法就是,将<reporting>内的plugin声明,转换为如下形式:

[html]  view plain copy
  1. <plugin>  
  2.   <groupId>org.apache.maven.plugins</groupId>  
  3.   <artifactId>maven-site-plugin</artifactId>  
  4.   <version>3.0</version>  
  5.   <configuration>  
  6.     <reportPlugins>  
  7.       <plugin>  
  8.         <groupId>org.apache.maven.plugins</groupId>  
  9.         <artifactId>maven-checkstyle-plugin</artifactId>  
  10.       </plugin>  
  11.       <plugin>  
  12.         <groupId>org.apache.maven.plugins</groupId>  
  13.         <artifactId>maven-pmd-plugin</artifactId>  
  14.       </plugin>  
  15.     </reportPlugins>  
  16.   </configuration>  
  17. </plugin>  


注意,这里的plugin声明已经成为了maven-site-plugin中的一个configuration项,已不再享有原来plugin那种继承规则,在可视化编辑器内也再没有语法提示。

还有一点就是,在3.0版本中,在maven-site-plugin内声明的插件是可以忽略version的,maven-site-plugin会按照如下顺序查找:

1. build.plugins

2. build.pluginsManagement

3.repository(在repository中查找可能会使用Snapshot的插件,和maven插件一样规则)


至此,改动已经完成,运行mvn clean site即可看见project-reports.html文件,打开所期望的报告页面了。


三、内部工作原理

刚开始时候,很难明白maven中packaging、phase和goal之间的关系,后来搞清楚了,项目搭出一个样子的时候,又来一个新的问题——报告

maven在pom model 4.0定义中,特别为报告开辟了一个与build同级的专用节点——<reporting>,在reporting内可以声明一个plugins然后写上各种报告插件,(在Maven2.x中)运行mvn site即可生成一个很完整的项目报告。这个是怎么做到的呢,下面来一探究竟。


1. 首先,看mvn site这个命令做了什么?明显执行了site这个phase,但是phase是不能执行的,执行的是插件,那么就看看是什么插件绑定到site这个phase上。通过Effective POM看到,显然maven-site-plugin:site这个操作绑定到了site这个phase上

[html]  view plain copy
  1. <plugin>  
  2.   <artifactId>maven-site-plugin</artifactId>  
  3.   <version>2.3</version>  
  4.   <executions>  
  5.     <execution>  
  6.       <id>default-site</id>  
  7.       <phase>site</phase>  
  8.       <goals>  
  9.         <goal>site</goal>  
  10.       </goals>  
  11.     </execution>  
  12.   </executions>  
  13. </plugin>  

2. 其次,maven-site-plugin怎么知道reporting声明的插件呢?maven-site-plugin作为maven的核心插件,怎么说也有点特权吧。的确,在Effective POM内可以发现,其实maven做了点手脚,将reporting里面的内容转化成了maven-site-plugin下的一个配置项~_~

如果reporting里面什么都没有配置,maven就会继承最原始的配置(类似Java里面的Object一样),给maven-site-plugin加上一个默认的报告插件——maven-project-info-report-plugin,在Effective POM里面可以看到:

[html]  view plain copy
  1. <plugin>  
  2.   <artifactId>maven-site-plugin</artifactId>  
  3.   <version>2.3</version>  
  4.   ...  
  5.   <configuration>  
  6.     <outputDirectory>E:\Ming\Workspace\Eclipse\3.7\org.cst.javaee.project\target\site</outputDirectory>  
  7.     <reportPlugins>  
  8.       <reportPlugin>  
  9.         <groupId>org.apache.maven.plugins</groupId>  
  10.         <artifactId>maven-project-info-reports-plugin</artifactId>  
  11.       </reportPlugin>  
  12.     </reportPlugins>  
  13.   </configuration>  
  14. </plugin>  
如果在reporting里面添加了报告插件,maven就会在现有基础上把reporting.plugins里面的plugin都转化成reportPlugin并且附加到maven-site-plugin的configuration.reportPlugins里面。

**注意:这个是关键,在maven-site-plugin:3.0中reportPlugins内的项由reportPlugin转为plugin,这点转变使得maven原来所做的转化操作无效,因为maven-site-plugin:3.0不再解释reportPlugins.reportPlugin转而解释reportPlugins.plugin,所以在使用maven-site-plugin:3.0的时候必须在插件的configuration.reportPlugins.plugin内声明报告插件,而不能使用reporting。并且Maven3只能使用maven-site-plugin:3.0,所以一定要注意Maven2升级至Maven3时的变动!

3. 最后,maven-site-plugin怎样调用报告插件的?这个就太简单了,插件信息都知道了想怎么调用就怎么调用!那么goal呢,配置并没有显示声明goal喔?原来maven-site-plugin也有自己的限制,它所只支持某些报告插件(当然,可能有方法通过配置让它知道更多的报告插件,这个就没研究过了),所支持插件列表在官方文档上有列出:http://maven.apache.org/plugins/maven-site-plugin/maven-3.html#Plugins_Compatibility_Matrix_for_Maven_3

文章的最后,回应一下《maven-site-plugin笔记——2.3到3.0之间的变化》最后提的问题,为何新版配置没有生成index.html,解决办法就是在maven-site-plugin:3.0的configuration中添加maven-project-info-reports-plugin的声明即可



依赖冲突:

这个是dependency的GA一样但V不同,Maven自2.9(还是2.0.9,不清楚了)开始为了确保确定性,采用如下方法解决:

1. 依赖路径浅的优先:

假设,A->B->slf4j:1.6.2,A->C->E->slf4j:1.4.1,则slf4j:1.6.2优先

2. 声明优先,如果在dependencyManagement中声明的话会优先采用对应插件

3. 覆写优先,子POM内声明的优先于父POM中的依赖


*上述的依赖均假定为compile依赖


********************************************************************************************************

重复类的类加载:

同样是2.9还是2.0.9开始,Maven在classpath中下了一点功夫,由于各个容器对类加载规则的不一,所以以下仅讨论对Eclipse的类路径影响。

现在,由Maven插件向Eclipse提供的类路径是有顺序的,以当前工程为原点,加载顺序为:

1. 首先加载test-class,这个m2eclipse的jira上显示为fixed的一个issue:http://jira.codehaus.org/browse/MECLIPSE-318

2. 当前POM的依赖,顺序按照pom.xml内使用的顺序(由上至下,靠上优先加载)

3. 父POM使用的依赖会被最后加载


*上述观点均为资料收集后理解结果,并未经过测试!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值