Jenkins中的Android打包任务设计

Stella981
• 阅读 530

Jenkins持续集成Unity游戏项目

Jenkins的安装部署和配置

Jenkins中的Android打包任务设计

Jenkins中的iOS打包任务设计

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

Jenkins中的Android打包任务设计

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>

#打包流程 Jenkins中的Android打包任务设计 ##CheckOut 使用的是Jenkins的SVN自己输出但是这里有个特殊点我们的项目由于前期的历史问题主干与分支是同级目录,所以在使用获取SVN目录时候使用的是我自己的脚本如下: Jenkins中的Android打包任务设计 ##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来一起学习。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
1. 容器化部署一套云服务 第一讲 Jenkins(Docker + Jenkins + Yii2 + 云服务器))
容器化部署一套云服务系列1\.容器化部署一套云服务之Jenkins(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fjackson0714%2Fp%2Fdeploy1.html)一、购买服务器服务器!caeef00
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这