使用Gradle与Ant实现多个apk的自动打包

使用Gradle与Ant实现不同的apk的打包
说下应用场景:
公司有这样的需求:对于同一份代码,需要生成N多个不同的Apk,包括应用图标不同,启动图不同,包名不同等,而且后续业务发展,可能这些Apk的数量会越来越多,如果我们打包一个就修改一下包名,替换下图片,那这样就会显得非常的麻烦,而且公司也没有多余的人力来做这个,所以就想到了自动打包。早就想写篇博客总结下,一直拖到现在。如果你的公司也有类似的需求,那希望这篇文章会对你有用。
一、ant环境的搭建
1、下载ant压缩包:ant打包工具
2、这里写图片描述,解压到任意盘,我电脑上是解压在D盘;
3、配置环境变量,新建一个环境变量,名为ANT_HOME,值为ant的根目录,如D:\apache-ant-1.9.3;然后在path中加入%ANT_HOME%\bin;同时还需要把sdk的tools路径配置到环境变量path中;
4、要使ant支持循环打包,需要下载ant-contrib-1.0b3.jar,这个自行去网上搜索下载,然后将其拷贝到apache-ant-1.9.3\lib目录下;
二、生成build.xml文件
可以从网上下载一个模版,也可以自己通过命令生成:cmd打开dos窗口,切换到你的项目路径,输入命令”android update project -t 2 -p .“,其中的2为androidid,可通过命令android list查看id;执行完后,你会发现在你的项目根目录下,会多出三个文件:local.properties、proguard-project.txt以及build.xml

三、根据实际情况,配置build.xml
要通过自动打包,就要能自动修改appIcon,启动图,keystore的名字(keystore的密码这里默认都是一样的,只是名字不同),如果有添加分享,那这里还会涉及到替换微信分享的WXEntryActivity以及qq分享的id等等;
以两个Apk打包为例,一个appName为demo1,包名为com.test.demo1,另一个叫demo2,包名为com.test.demo2;
1)新建一个xml文件,填入apk需要的信息,

<?xml version="1.0" encoding="UTF-8"?>
<key>
    <apkInfo>
        <packageName>demo1</packageName>
        <alias>aliasdemo1</alias>(ps:打包用的alias)
        <appName>示例1</appName>
    </apkInfo>
    <apkInfo>
        <packageName>demo2</packageName>
        <alias>aliasdemo2</alias>
        <appName>示例2</appName>
</apkInfo>
</key>

保存,放到任意盘,我这里把它放到项目的根目录下;

2)在E盘新建两个个文件夹,一个为icon,用于存放app图标,一个为apkFile,用于存放打包后的apk;
在icon文件夹下新建三个文件夹,分别为mipmap-hdpi、mipmap-xdpi以及mipmap-xxdpi,然后分别在这三个文件夹下新建demo1和demo2两个apk文件夹,名称以包名最后一个字段命名,如果包名为com.test.demo1,那么就命名为demo1,接着就可以在文件夹中放入你的图标和图片了。

3)把apkInfo.xml中的数据解析,拼成字符串,填入local..properties中,这里最好写一个java程序,去解析,记住,涉及到的中文,要转化为ascii码。格式如下:
这里写图片描述

4)把gradle命令配置到环境变量,用于打包apk
在环境变量的path中加入:
这里写图片描述

5)配置build.gradle文件
*先在local.properties文件中填入appReleaseDir=E:\apkFile;
*

android {
    signingConfigs {
        release {
            keyAlias "demo1"
            keyPassword "123456"
            storeFile file(
                    "E:/demo1.jks"
            )
            storePassword "123"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }

    //修改生成的apk名字
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            if (variant.buildType.name.equals('release')) {
                // APK输出文件名规则:aiyou-版本名-市场-release.apk
                def releaseApkName = defaultConfig.applicationId + '_' + defaultConfig.versionName + '_release.apk'
                // appReleaseDir对应local.properties里面定义的路径
                output.outputFile = new File(appReleaseDir, releaseApkName)
            }
            if (variant.buildType.name.equals('beta')) {
            }
            if (variant.buildType.name.equals('debug')) {

            }
        }
    }
}

6)配置build.xml文件
先贴出代码:

<project name="demo1" default="packageAPK" basedir=".">
    <property name="sdk.dir" location="F:/AppData/Local/sdk" />
    <property name="java.dir" location="C:/Program Files/Java/jdk1.8.0_25" />
    <property name="project_org.dir" value="G:/project/demo1" />
    <property name="manifest.dir" value="G:/project/demo1/app/src/main" />
    <property name="strings.dir" value="G:/project/demo1/app/src/main/res/values" />
    <property name="srcSplash.dir"
        value="G:/project/demo1/app/src/main/java/com/test/demo1/utils" />
    <property name="wxapi.dir" value="G:/project/demo1/wxdirectory" />
    <property name="apk.out.dir" value="E:/apkFile" />
    <property name="app.build.dir" value="G:/project/demo1/app/build" />
    <property name="com.test.dir"
        value="G:/project/demo1/app/src/main/java/com/test" />
    <property name="gradle"
      value="C:/Users/Administrator/.gradle/wapper/dists/gradle-2.2.1-all/c64ysjskjslkjlsjlkjskl0w53/gradle-2.2.1/bin/gradle.bat" />

<property name="hdpi.dir" value="G:/project/demo1/app/src/main/res/mipmap-hdpi" />
<property name="xhdpi.dir" value="G:/project/demo1/app/src/main/res/mipmap-xhdpi" />
<property name="xxhdpi.dir" value="G:/project/demo1/app/src/main/res/mipmap-xxhdpi" />
<property name="hdpi.new.dir" value="E:/icon/mipmap-hdpi" />
<property name="xhdpi.new.dir" value="E:/icon/mipmap-xhdpi" />
<property name="xxhdpi.new.dir" value="E:/icon/mipmap-xxhdpi" />
<property name="app_project.dir" value="${project_org.dir}/app" />

<property file="local.properties"/>
    <!-- 使用第三方的ant包,使ant支持for循环-->
    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
        <classpath>
            <pathelement location="./ant-contrib-1.0b3.jar" />
        </classpath>
    </taskdef>
    <!-- 设置路径和初始化环境 -->
    <path id="android.antlibs">
        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
    </path>
    <!--循环打包 -->
    <target name="deploy">
        <foreach target="init" list="${key}" param="nameandchannel" delimiter=","></foreach>
    </target>
    <!-- 初始化 -->
    <target name="init">
        <propertyregex override="true" property="packageName" input="${nameandchannel}" regexp="(.*):" select="\1" />
        <propertyregex override="true" property="alias" input="${nameandchannel}" regexp=":(.*)%" select="\1" />
        <propertyregex override="true" property="appname" input="${nameandchannel}" regexp="%(.*)" select="\1" />
        <!--复制程序图片和启动图片-->
        <copy todir="${hdpi.dir}" overwrite="true">
            <fileset dir="${hdpi.new.dir}/${packageName}" includes="**/*" />
        </copy>
        <copy todir="${xhdpi.dir}" overwrite="true">
            <fileset dir="${xhdpi.new.dir}/${packageName}" includes="**/*" />
        </copy>
        <copy todir="${xxhdpi.dir}" overwrite="true">
            <fileset dir="${xxhdpi.new.dir}/${packageName}" includes="**/*" />
        </copy>
        <!--修改appname-->
        <replaceregexp flags="g" byline="true" encoding="UTF-8">
            <regexp pattern='\x3Cstring name="app_name"\x3E(.*)' />
            <substitution expression='&lt;string name="app_name"&gt;${appname}' />
            <fileset dir="${strings.dir}" includes="strings.xml" />
        </replaceregexp>

        <!--修改清单文件AndroidManifest文件中的包名-->
        <replaceregexp flags="g" byline="false" encoding="UTF-8">
            <regexp pattern='package="com.test.(.*)"' />
            <substitution expression='package="com.test.${packageName}"' />
            <fileset dir="${manifest.dir}" includes="AndroidManifest.xml" />
        </replaceregexp>
        <replaceregexp flags="g" encoding="UTF-8" byline="true">
            <regexp pattern="import com.test.(.*).R;"/>
            <substitution expression="import com.test.${packageName}.R;"/>
            <fileset dir="${manifest.dir}/java" includes="**/*.java"/>
        </replaceregexp>
        <!--修改build.gradle文件中的applicationId-->
        <replaceregexp flags="g" encoding="UTF-8" byline="true">
            <regexp pattern='applicationId "com.test.(.*)"' />
            <substitution expression='applicationId "com.test.${packageName}"' />
            <fileset dir="${app_project.dir}" includes="build.gradle" />
        </replaceregexp>
        <!--修改build.gradle文件中的alias-->
        <replaceregexp flags="g" encoding="UTF-8" byline="true">
            <regexp pattern='keyAlias "(.*)"' />
            <substitution expression='keyAlias "${alias}"' />
            <fileset dir="${app_project.dir}" includes="build.gradle" />
        </replaceregexp>
        <!--修改build.gradle文件中的keystore地址-->
        <replaceregexp flags="g" encoding="UTF-8" byline="true">
            <regexp pattern='"E:/(.*).jks"' />
            <substitution expression='"E:/${packageName}.jks"' />
            <fileset dir="${app_project.dir}" includes="build.gradle" />
        </replaceregexp>
        <antcall target="gradleRelease" />
    </target>
    <!--打包编译-->
    <target name="generateDebugSources">
        <exec executable="${gradle}" failonerror="true">
            <arg value="generateDebugSources" />
        </exec>
    </target>
    <target name="generateDebugAndroidTestSources">
        <exec executable="${gradle}" failonerror="true">
            <arg value="generateDebugAndroidTestSources" />
        </exec>
    </target>
<target name="gradleRelease" depends="generateDebugSources,generateDebugAndroidTestSources">
        <exec executable="${gradle}" failonerror="true">
            <arg value="assembleRelease" />
        </exec>
    </target>
</project>

7)开启自动循环打包
打开cmd命令窗口,切换路径到我们的项目根目录下,输入ant deploy,回车,即可开始自动打包。

PS:准备过程可能有点麻烦,这里使用的build.xml中的命令是通过正则匹配去替换文件中的内容,可能也会有更方便的批量打包方法,没有再去想了,对于上面有不懂的可以自行网上搜索查询,应该都会找到解答的,也可以留言,共同探讨android技术。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值