文档章节

Jenkins中的Android打包任务设计

Lohanry
 Lohanry
发布于 2017/04/30 18:19
字数 1889
阅读 442
收藏 16

Jenkins持续集成Unity游戏项目

Jenkins的安装部署和配置

Jenkins中的Android打包任务设计

Jenkins中的iOS打包任务设计

Jenkins中的测试任务设计 #Jenkins中的Android打包任务设计 #实现界面 实现界面 #Unity项目的结构

打包结构

Untiy代码管理中分支是上线的版本,所以主要以它为版本进行分析。 Unity导出时候分三个版本,官网,第三方,腾讯。以宏来控制版本,和脚本删除不需要的脚本 由于使用的是Jenkins全部是命令行出包,Unity打包脚本如下

static void ExportGYTProject_Online()
    {
        getCMDArgs();
        string[] NeedToDel = {
            "Assets/Resources/DaBao",
            "Assets/Resources/Audio",
            "Assets/Resources/BackgroundPrefabs",
            "Assets/Resources/BattleBackground",
            "Assets/Resources/Maps"};
        doDelWithRelativePath(NeedToDel);
        _LanguageBar.ToTraditionForAntBuild();
        PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Android, "XXXX");
        ExportAndroidProject(ExportPath);
    }
 static void getCMDArgs() {
        foreach (string arg in System.Environment.GetCommandLineArgs()){
            if (arg.StartsWith("-ExportPath")){
                ExportPath = arg.Split('=')[1].Trim('"');
            }else if (arg.StartsWith("-UseWeTest")) {
                UseWeTest = arg.Split('=')[1].Trim('"').Equals("true");
                Debug.Log(UseWeTest);
;            }
            Debug.Log(arg);
        }
        if (ExportPath.Equals("")){
            throw new NullReferenceException("缺少-ExportPath参数");
        }else{
            Debug.Log("导出路径:" + ExportPath);
        }
    }

代码中ExportGYTProject_Online为需要调用Unity的CMD命令,getCMDArgs为对进行传入Unity命令行的命令解析

System.Environment.GetCommandLineArgs() //获取命令行参数

导出Android的工程至指定目录 #Android工程区分 ##官网的Android模板 都是只需要修改Mainfast.xml中channelid的参数就可以,所以官网的Android模板只有一个,每次通过Ant来修改channelid然后直接执行Ant release即可,并移动到指定目录

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" >
	<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
	<property name="_APKPATH" value=""/>
	<property name="_game_channelid" value=""/>
	<target name="BuildAPK">
		<antcall target="BuildAPK_All"/>
		<antcall target="BuildAPK_Alone"/>
	</target>
	<target name="BuildAPK_Alone" if="${isBuildAlone}">  
		<foreach list="${channelList}" target="UpdateChannelid" param="channel_id" delimiter=",">
			
		</foreach>
  	</target>
  	<target name="UpdateChannelid">
  		<propertyregex property="_temp_game_channelid"  
                  input="${channel_id}"  
                  regexp="&quot;?(.*)###"  
                  select="\1"  
                  casesensitive="false" />
        <echo message="${_temp_game_channelid}"/>
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;game_channelid&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;game_channelid&quot; android:value=&quot;${_temp_game_channelid}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
		<echo message="${channel_id}"/>
		<propertyregex property="_temp_platform_channel_id"  
                  input="${channel_id}"  
                  regexp="###(.*[^&quot;])"  
                  select="\1"  
                  casesensitive="false" />
        <echo message="${_temp_platform_channel_id}"/>
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;platform_channel_id&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;platform_channel_id&quot; android:value=&quot;${_temp_platform_channel_id}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
		<antcall target="release"/>
  		<copy  
            file="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk"  
            tofile="${APKPATH}/${ant.project.name}-v${VERSIONNAME}-${_temp_game_channelid}-${_temp_platform_channel_id}-unsigned.apk" />
  	</target>
  	<target name="BuildAPK_All" unless="${isBuildAlone}">  
  		<var name="_game_channelid" value="${game_channelid}"/>
    	<antcall target="BuildGW"/>
    	<var name="_game_channelid" value="${CPSgame_channelid}"/>
    	<antcall target="BuildCPS"/>
  	</target>

  	<target name="BuildCPS">
  		<echo message="${VERSIONNAME}/${VERSIONCODE}"/>
		<echo message="打包官网CPS版本!" /> 
		<antcall target="UpdateVersionName"/>
		<antcall target="UpdateVersionCode"/>
		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;game_channelid&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;game_channelid&quot; android:value=&quot;${CPSgame_channelid}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
		<var name="_APKPATH" value="${APKPATH}"/>
		<foreach list="${CPSplatform_channel_idList}" target="Updateplatform_channel_idForMu" param="channel_id" delimiter=",">
			
		</foreach>
  	</target>

  	<target name="BuildGW">
  		<echo message="${VERSIONNAME}/${VERSIONCODE}"/>
		<echo message="打包官网多渠道版本!" /> 
		<antcall target="UpdateVersionName"/>
		<antcall target="UpdateVersionCode"/>
		<antcall target="Updategame_channelid"/>
		<var name="_APKPATH" value="${APKPATH}"/>
		<foreach list="${platform_channel_idList}" target="Updateplatform_channel_idForMu" param="channel_id" delimiter=",">
			
		</foreach>
  	</target>

  	<target name="UpdateVersionName">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionName=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionName=&quot;${VERSIONNAME}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

  	<target name="UpdateVersionCode">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionCode=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionCode=&quot;${VERSIONCODE}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

  	<target name="Updategame_channelid">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;game_channelid&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;game_channelid&quot; android:value=&quot;${game_channelid}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>


  	<target name="Updateplatform_channel_idForMu"> <!-- 多渠道循环 -->
  		<echo message="${_APKPATH}"/>
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;platform_channel_id&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;platform_channel_id&quot; android:value=&quot;${channel_id}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  		<antcall target="release"/>
  		<copy  
            file="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk"  
            tofile="${APKPATH}/${ant.project.name}-v${VERSIONNAME}-${_game_channelid}-${channel_id}-unsigned.apk" />
  	</target>
</project>

##第三方的Android模板 由于每个渠道都是需要接入指定的SDK。一开始考虑接入所有SDK,然后通过修改XML中的配置参数然后来调用不同SDK,然后发现部分SDK有冲突而且包会变得巨大无比,然后修改为每个渠道一个Android模板,然后在导出指定版本的Unity后,移动Assets下的目录到Android工程包,然后执行Ant release。

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" >
	<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
	<target name="BuildAPK">
		<antcall target="preBuildProject"/>
		<echo message="${VERSIONNAME}/${VERSIONCODE}"/>
		<antcall target="UpdateVersionName"/>
		<antcall target="UpdateVersionCode"/>
		<antcall target="Updateplatform_channel_id"/>
		<antcall target="Updategame_channelid"/>
		<antcall target="release"/>
		<copy  
            file="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk"  
            tofile="${APKPATH}/${ant.project.name}-v${VERSIONNAME}-${game_channelid}-${platform_channel_id}-unsigned.apk" />
  	</target>
  	
  	<target name="preBuildProject">
  		<foreach target="preBuildSubProject" param="_path">
  			<path>
  				<dirset dir=".." includes="/*"/>
  			</path>
  		</foreach>
  	</target>
  	<target name="UpdateVersionName">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionName=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionName=&quot;${VERSIONNAME}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>
  	<target name="UpdateVersionCode">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionCode=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionCode=&quot;${VERSIONCODE}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>
  	<target name="Updateplatform_channel_id">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;platform_channel_id&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;platform_channel_id&quot; android:value=&quot;${platform_channel_id}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>
  	<target name="Updategame_channelid">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;game_channelid&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;game_channelid&quot; android:value=&quot;${game_channelid}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>
</project>

##腾讯的Android模板 由于比较奇特,所以单独抽取了出来进行打包。

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" >
	<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
	<target name="BuildAPK">
		<echo message="${VERSIONNAME}/${VERSIONCODE}"/>
		<antcall target="UpdateVersionName"/>
		<antcall target="UpdateVersionCode"/>
		<antcall target="Updateplatform_channel_id"/>
		<antcall target="Updategame_channelid"/>
		<antcall target="release"/>
		<copy  
            file="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk"  
            tofile="${APKPATH}/${ant.project.name}-v${VERSIONNAME}-${game_channelid}-${platform_channel_id}-unsigned.apk" />
  	</target>
  	<target name="UpdateVersionName">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionName=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionName=&quot;${VERSIONNAME}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

  	<target name="UpdateVersionCode">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:versionCode=&quot;(.*?)&quot;"/>
			<substitution expression="android:versionCode=&quot;${VERSIONCODE}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

  	<target name="Updateplatform_channel_id">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;platform_channel_id&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;platform_channel_id&quot; android:value=&quot;${platform_channel_id}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

  	<target name="Updategame_channelid">
  		<replaceregexp byline="false" encoding="UTF-8" flags="g">
			<regexp pattern="android:name=&quot;game_channelid&quot; android:value=&quot;(.*?)&quot;"/>
			<substitution expression="android:name=&quot;game_channelid&quot; android:value=&quot;${game_channelid}&quot;" />
			<fileset dir=""
				includes="AndroidManifest.xml" />
		</replaceregexp>
  	</target>

</project>

#打包流程 打包流程 ##CheckOut 使用的是Jenkins的SVN自己输出但是这里有个特殊点我们的项目由于前期的历史问题主干与分支是同级目录,所以在使用获取SVN目录时候使用的是我自己的脚本如下: SVN目录 ##reBuildAndroidLib 由于是Unity导出时候分主工程和一个Lib在导入后需要重新应用Lib一开始使用的手工加上引用,但是后来发现Android命令可以直接引用,但是没来的及修改代码参考如下:

import sys;
import os;

filePath = sys.argv[1] 
ShareSDKPath = sys.argv[2] 
file = open(filePath)
count = 1;
isNeedAdd = 1;
while 1:
    line = file.readline()
    if not line:
        break
    if "ShareSDK" in line:
        isNeedAdd = 0;
    if "android.library.reference" in line:
        count = count +1;
file.close();
if isNeedAdd == 1:
    file = open(filePath,'a');
    ShareSDKPath = ShareSDKPath.replace('\\','/').replace('//','/');
    file.write("\nandroid.library.reference.%d=%s" % (count,ShareSDKPath));
    file.close();
    //这个脚本只能作为参考因为有挺多问题了,但是由于懒得修改就一直在用,可以用Android命令来替代

##reBuildAndroid 这里的--tatget 3 是根据自己的本地Android来设置的,可以参考命令说明修改

cd %1
@call ant clean
@call android update project -p ./ --subprojects --target 3

##BuildApk 代码上面已经给出 ##SignApk 采用python脚本,由于这个脚本不是我们提供的,所以不贴出脚本了,也比较简单的。根据不同渠道签名。 ##加固混淆包 采用python脚本,由于加固的提供方是公司购买的也不提供代码了,由于他们不支持curl所以都是网页提交的,这里的python脚本主要是直接进行模拟网页操作提交。 ##分析APK文件 使用的JAVA来实现。Java代码比较多,我就说下思路,或者有空我开个新的帖子说下Ant的扩展实现。 思路根据APK使用CMD命令来调用Android命令行工具获取返回值,然后进行输出。 ##QA测试 QA测试使用WeTest,在Jenkins的打包选项内可以进行设置是否集成Wetest,然后直接进行测试 ##发布 发布到百度云传给运营商,然后上线。

#总结 其实这些都已经非常的概括的来说明整个思路了,事实上每一步流程都可以开一个日志来说明是如何分析,有空我将会单独开日志来解释。感谢大家阅读,如果有兴趣可以添加我的QQ792667487来一起学习。

© 著作权归作者所有

共有 人打赏支持
Lohanry

Lohanry

粉丝 6
博文 10
码字总数 11765
作品 1
宁波
程序员
私信 提问
Android直接用手机打包apk!

你没有看错,用手机浏览器访问Jenkins,就可以打包apk,并生成下载二维码,发送邮件通知测试人员下载,从此解放双手,告别打包测试。先上本人手机邮箱收到的打包成功通知效果图: 废话少说,...

Zachary46
2018/08/01
0
0
Jenkins中使用ant管理Android应用开发生命周期

软件环境 OS:CentOS 6.0 64-bit Android SDK:adt-bundle-linux-x86_64 Jenkins:1.529 Ant:1.8.2 配置管理 1.Jenkins中配置JDK,直接配置1.7+以上JDK。过程略。 2.把Android工程改造成具有A...

miscellanea
2013/11/19
0
0
自动化构建Android项目 ---- Jenkins自动化部署学习笔记(二)

  上篇文章跟大家分享了在Windows上安装Jenkins的方法,这篇文章来跟大家分享一下利用Jenkins自动化构建Android项目: 一、所需准备: Android项目上传至版本管理平台,这里我准备了Githu...

onestravel
2018/05/22
0
0
jenkins maven管理的android项目怎么打包apk

RT,我在jenkins已经建好了maven项目,代码也已经拉去好了,build也通过了,请问怎么打包成apk呢? 在网上查了一些资料: 1、主要就是ant打包方式,但是我的项目是maven管理的,应该行不通吧...

hzy00
2014/09/23
1K
2
Jenkins +Gradle实现Android自动化构建(学习笔记三十二)

https://blog.csdn.net/mabeijianxi/article/details/52680283 http://www.liuling123.com/2016/10/jenkins-gradle-auto-build.html Jenkins简介 Jenkins是一个开源软件项目,旨在提供一个开......

sktj
2018/05/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS5.11配置Let's Encrypt免费证书

安装环境: [root@WQ02 opt]# lsb_release -aLSB Version::core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd6......

m_lm
24分钟前
1
0
看看Canonical分享的2018年的十大Linux Snap

导读 Linux在2018年最令人耳目一新的一个方面是Snaps的普及。 Canonical透露,集装箱化的包装已经取得了巨大的成功。今天,Ubuntu制造商分享了2018年的十大Snap。 随着2018年即将结束,我发现...

问题终结者
36分钟前
2
0
天啦噜!在家和爱豆玩"剪刀石头布",阿里工程师如何办到?

阿里妹导读:如今,90、00后一代成为消费主力,补贴、打折、优惠等“价格战”已很难建立起忠诚度,如何与年轻人建立更深层次的情感共鸣?互动就是一种很好的方式,它能让用户更深度的参与品牌...

阿里云官方博客
今天
1
0
聊聊flink的Table API及SQL Programs

序 本文主要研究一下flink的Table API及SQL Programs 实例 // for batch programs use ExecutionEnvironment instead of StreamExecutionEnvironmentStreamExecutionEnvironment env = Stre......

go4it
今天
3
0
mysqldump应用

备份单个库/表数据或库/表结构 命令行下具体用法如下: mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 备份文件名 1、导出数据库为dbname的表结构(其中用戶名為root,密码为dbpasswd,生成的...

阿dai
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部