android开发之Jenkins+Gradle实现android开发持续集成、多渠道打包

需求:
我今天在项目上加了一个功能,那么一个好的项目开发流程必然得跑单元测试,意思是:“改一次代码,需要手动跑一次单元测试,来检验代码在当前情况下是否能运行成功!”,但每次都需要手动跑的话就太累了,因为一个新增项目功能,我一天下来可能会改十几次代码。

因此我们将目标锁定一下,只要某个工具能实时监控,每当svn上项目版本更改后,我就自动构建,然后跑一次单元测试,当然也可以改成每天一次或者每小时一次来监控svn上项目版本更改情况(随你配置,后面会讲),这样岂不是妙湛!

一、Jenkins简介

Jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上。同时Jenkins能实现监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。Jenkins的前身是Hudson,是一个可扩展的持续集成引擎。

二、Jenkins安装与配置

  • 下载地址1:http://mirrors.jenkins-ci.org/war/latest/jenkins.war
  • 下载地址2:http://pan.baidu.com/s/1jGHykHg 提取密码:3wov
  • 安装:将下载的jenkins.war包直接放到tomcat下的webapps目录下,然后启动tomcat即可安装完成,接下来登录:http://localhost:8080/jenkins就能进入jenkins系统页面,在此不说tomcat如何配置环境变量
  • 编码问题:

    • 当你进入jenkins系统管理页面,会出现如图提示,可修改tomcat的server.xml配置,在Connector 标签添加上 URIEncoding=”UTF-8” 。
      这里写图片描述

    这里写图片描述

  • 配置:

    • 点击“系统管理” –> “Configure Global Security”
      这里写图片描述

      这里写图片描述
      首先先添加一个administer用户作为超级管理员,全部权限都打勾,如图admin用户。保存,重启。用刚刚添加的超级管理员作为账号名注册一个账号,即可拥有超级管理员权限。
      这里写图片描述

    • JDKGradle如果系统环境变量配置好的话就不用再配置,用默认的就行。
    • 邮件通知:点击“系统管理”–> “系统设置”
      这里写图片描述

三、Jenkins Gradle插件安装

  • 点击“系统管理”–> “管理插件” –> “可选插件” 选中Gradle plugin插件安装重启即可。
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • 设置代理
    这里写图片描述

四、Jenkins新建任务

  • 点击“新建”
    这里写图片描述

  • 选择“源码系统”
    这里写图片描述

    Repository URL: svn 的 的地址,如果输入的地址需要输入用户名和密码,将自动跳出红色的提示信息,点击”enter credential” 进入设置svn 用户名。

  • 选择“构建触发器”

    来到了这一步,实属不易,这里就是我们的天堂,就能完成“每当svn上项目版本更改后,我就自动构建,然后跑一次单元测试,当然也可以改成每天一次或者每小时一次来监控svn上项目版本更改情况。

    这里写图片描述

    • Build periodically:周期进行项目构建(它不关心源码是否发生变化)

    • Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作,这里我选择它

  • 选择“日程表”
    这里写图片描述

    第一个参数代表的是分钟 minute,取值 0~59;
    第二个参数代表的是小时 hour,取值 0~23;
    第三个参数代表的是天 day,取值 1~31;
    第四个参数代表的是月 month,取值 1~12;
    第五个参数代表的是星期 week,取值 0~7,0 和 7 都是表示星期天。
    如H/5 * * * * 表示的就是每5分钟检查一次源码变化。

  • 选择 “构建”,添加“Invoke Gradle script”
    这里写图片描述
    这里写图片描述
    这里写图片描述
    Switches :即gradle 后面所接的命令。上面相当于执行gradle clean build命令。

  • 构建后操作:构建失败可以发送邮件通知
    这里写图片描述
    这里写图片描述

五、Gradle介绍

Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具。现在已是android的默认构建工具了。

六、android build.gradle配置

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.6'//依赖
    }
}

apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')//添加android依赖libs
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"
    //签名
    signingConfigs {
        myConfig {
            storeFile file("debug.keystore")
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
    }

    defaultConfig {
        versionCode 1
        versionName getVersionName()
        minSdkVersion 8
        targetSdkVersion 17
    }

    //渠道
    productFlavors {
        google{

        }
        tantai{

        }
    }

    buildTypes{
        release {
            signingConfig signingConfigs.myConfig
            runProguard true
            proguardFile 'proguard.cfg'
        }
    }

    sourceSets {
        main {
            manifest {
                srcFile 'AndroidManifest.xml'
            }
            java {
                srcDir 'src'
            }
            res {
                srcDir 'res'
            }
            assets {
                srcDir 'assets'
            }
            resources {
                srcDir 'src'
            }
            aidl {
                srcDir 'src'
            }
        }
    }
}


tasks.withType(Compile) {
    options.encoding = "UTF-8"
}
//替换AndroidManifest.xml的UMENG_CHANNEL_VALUE字符串为渠道名称
android.applicationVariants.all{ variant -> 
    variant.processManifest.doLast{ 
        copy{
            from("${buildDir}/manifests"){
                include "${variant.dirName}/AndroidManifest.xml"
            }
            into("${buildDir}/manifests/$variant.name")

            filter{
                String line -> line.replaceAll("UMENG_CHANNEL_VALUE", "$variant.name")
            }

            variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
        }    
   }
}

遇到的问题:tomcat下gradle 构建如果遇到Could not load Logmanager “org.apache.juli.ClassLoaderLogManager”。

解决:注释掉catalina.bat里面的set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%即可!

注意:Gradle插件能配置成功的前提是:“你的项目中是由Gradle构建的,否则免谈”,Jenkins只是构建,得配合Gradle才能跑单元测试

七、手动跑单元测试

  • 登录:http://localhost:8080/jenkins/
  • 选择项目:
    这里写图片描述
  • 点击“立即构建”
    这里写图片描述
  • 点击“#1 / #2 …”查看执行情况
  • 点击“Console Output”–控制台输出
    这里写图片描述

八、Gradle实现的两种简单的多渠道打包方法

目前我掌握的方法有两种,都非常简单,用的都是Gradle Android插件里的productFlavors。

以友盟的多渠道打包为例,假设我们需要打包出如下渠道:UMENG, WANDOUJIA, YINGYONGBAO。

第一种方法,是需要创建文件的:

我们在写完我们的代码之后,在app/src下面,分别创建和main同级目录的文件夹umeng, wandoujia, yingyongbao,这三个文件夹里面都各只有一个AndroidManifest.xml文件,文件代码只需要如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="your.package.name">  
    <application>  

          <meta-data android:name="UMENG_CHANNEL" android:value="UMENG"/>  

    </application>  
</manifest> 

注意,上面的value的值要和你的渠道名所对应。比如wandoujia里面要对应为你豌豆荚上的渠道名(如WANDOUJAI)。
然后在你的build.gradle的android{}节点里面,添加productFlavors节点,代码如下:

android {  
    // 这里是你的其他配置  

    productFlavors{  
        umeng{  }  
        wandoujai {  }  
        yingyongbao{  }  
    }  
    // 你的其他配置  
}  

注意这里的flavors的名字要和你的文件夹的名字对应。这样配置之后,构建的就是多渠道的APK了。

第二种方法,不用创建那些文件的:

它使用的是Gradle Android插件里的另一个功能:manifestPlaceholders。

在这种方法中,你只需要在AndroidManifest.xml中,对友盟的渠道进行这样配置:

<meta-data  
    android:name="UMENG_CHANNEL"  
    android:value="${CHANNEL_NAME}" />  

然后同样使用productFlavors,不过这时它的配置是这样的:

android {  
    // 你的其他配置代码  

    productFlavors {  
        yingyongbao {  
            manifestPlaceholders = [ CHANNEL_NAME:"YINGYONGBAO"]  
        }  
        umeng {  
            manifestPlaceholders = [ CHANNEL_NAME:"UMENG" ]  
        }  
        wandoujia {  
            manifestPlaceholders = [ CHANNEL_NAME:"WANDOUJIA" ]  
        }  

    }  
    // 你的其他配置代码  
}  

在上面当中,我们也可以指定一个默认的渠道名,如果需要的话。指定默认的值是在defaultConfig节点当中添加如下内容:

manifestPlaceholders = [ CHANNEL_NAME:"Unspecified"]  

这里的Unspecified换成你实际上的默认的渠道名。

使用manifestPlaceholders的这种配置,同样适用于manifest的其他配置。比如你需要在不同渠道发布的apk里面,指定不同的启动Activity。比如在豌豆荚里面发布的,启动的Activity显示的是豌豆荚首发的界面,应用宝里面启动的是应用宝首发的界面(哈哈,有点坏),你就可以对你的activity的值使用①的方式,然后在productFlavors里面配置这个①的值。

①:${activity_name}

免责声明:
参考 http://my.oschina.net/uboluo/blog/157483
参考 http://blog.csdn.net/maosidiaoxian/article/details/42000913
参考:http://www.cnblogs.com/youxilua/archive/2013/05/20/3087935.html

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页