简介面向 Cocos 游戏开发者的安卓打包 ANT 全套配置包聚焦 Mac 环境下将 Cocos 项目编译、签名并输出可安装 APK 的完整流程适合已具备基础开发经验、需要打通发布环节的开发者参考。包内共 1634 个文件以 1525 个 html 文档、24 个 pom 与 24 个 jar 依赖、15 个 xsl 及若干 cmd、bat 脚本为主涵盖 ANT 运行所需的类库、说明文档与命令行入口压缩包约 9.12MB解压后可直接对照目录结构使用。目前已有 441 人学习。内容围绕 ANT 安装与环境变量配置、project.android 目录下 build.xml 参数调整、keystore 签名信息填写、ant release 执行以及 build.properties 编译优化等环节展开并给出编译报错、资源缺失等常见问题的排查思路。读者可据此理解 ANT 构建脚本的组织方式快速完成签名配置与打包验证减少发布环节反复试错的成本。1. Cocos安卓打包为什么还有人用ANT一个被Gradle掩盖的稳定路径安卓打包这件事在Cocos项目里经常被一句“用Gradle就行了”带过。但存量工程、渠道定制包、CI老脚本里ANT仍然是一条更可控的路产物路径固定、命令行参数少、签名流程透明出了问题看build.xml行号就能定位。它不新却适合接手老Cocos工程、需要按渠道批量出包、又不想重做整条构建链的人。ANT方案的核心不是“复古”而是把JDK、SDK、NDK、ANT四件事的版本咬合关系摆到明面上任何一个版本错位都会在打包时直接翻车。下面按环境、工程改造、签名渠道、避坑、验证五段拆开尽量把能抄的参数和要看住的日志写清楚。2. 环境搭建JDK、SDK、NDK、ANT四件套的版本咬合2.1 为什么ANT方案对JDK版本更挑剔ANT本身只是个构建调度器真正挑版本的是它调用的javac和Android SDK里的旧ant构建脚本。很多Cocos工程里的build.xml会引用SDK自带的tools/ant/build.xml里面默认把source和target写成1.6。JDK 8还能认这个参数JDK 11之后直接报“Source option 6 is no longer supported”日志里会指向javac那一行看起来像工程代码写错实际上是JDK太新。我一般会把JDK固定在8并且只给这个ANT工程用不跟系统里其他新项目混。ANT用1.9以上都行关键是ANT_HOME指向解压目录PATH里能直接敲ant。SDK这边不要只装最新platformANT工程通常依赖project.properties里的targetandroid-XX缺了对应platform会在aapt阶段报资源找不到。build-tools也要保留一套旧版本常见做法是留2830之间的一个版本给ANT用因为新build-tools的目录结构和旧ant脚本偶尔对不上。下面这张表是排错时最常对照的咬合关系不是绝对版本表而是“哪一项对不上会先炸”组件建议状态对不上的典型报错先看哪里JDK8JAVA_HOME指向JDK根目录Source option 6 is no longer supportedjavac日志行ANT1.9ANT_HOME可用ant: command not foundPATH顺序SDK platform与project.properties的target一致Failed to resolve targetplatforms/android-XXbuild-tools保留一套旧版本aapt not foundbuild-tools/目录名NDK与工程Android.mk兼容APP_PLATFORM或toolchain错误NDK_ROOT与jni/这张表的使用方式很直接先ant -version确认ANT本身没问题再java -version确认JDK是8然后进工程目录跑ant -p看target能不能被解析。如果ant -p就失败问题通常在环境变量或build.xml引用路径如果能列出target但编译失败再往JDK、SDK、NDK三层里找。不要一上来就改工程代码ANT打包的失败大多数发生在环境层。提示JDK 8的安装目录不要带空格Windows下尤其不要放在Program Files下面。ANT脚本里很多路径没有做引号包裹空格会把一个参数拆成两个。2.2 SDK/NDK目录与环境变量配置环境变量这一层Linux/macOS和Windows写法不同但目标一样让ant、java、ndk-build、aapt都能被找到。下面给的是bash写法路径用虚构的/opt/dev/前缀实际替换成自己的目录即可# JDK必须指向JDK根目录不是bin目录 export JAVA_HOME/opt/dev/jdk8 export PATH$JAVA_HOME/bin:$PATH # SDKANDROID_SDK_ROOT和ANDROID_HOME同时给兼容旧脚本 export ANDROID_SDK_ROOT/opt/dev/android-sdk export ANDROID_HOME$ANDROID_SDK_ROOT export PATH$ANDROID_SDK_ROOT/platform-tools:$PATH # NDKCocos的jni构建会读NDK_ROOT export NDK_ROOT/opt/dev/android-ndk export PATH$NDK_ROOT:$PATH # ANT指向解压目录 export ANT_HOME/opt/dev/ant export PATH$ANT_HOME/bin:$PATH # 验证顺序java - ant - ndk-build java -version ant -version ndk-build --version这段配置的逻辑是先固定JDK再把SDK和NDK挂进来最后挂ANT。JAVA_HOME指向JDK根目录是因为ANT和SDK脚本都会用$JAVA_HOME/bin/javac这种拼法如果指到bin会变成bin/bin/javac。ANDROID_SDK_ROOT和ANDROID_HOME同时给是为了兼容不同年代的脚本有的读前者有的读后者。NDK_ROOT是Cocos的jni构建常用变量ndk-build --version能跑通说明NDK目录和可执行权限都没问题。Windows下对应的是系统环境变量PATH里要包含%JAVA_HOME%\bin、%ANT_HOME%\bin、%ANDROID_SDK_ROOT%\platform-tools。改完之后一定要新开一个终端旧终端不会自动刷新环境变量。很多人改完变量直接在原窗口跑ant看到还是旧版本就以为配置没生效其实是窗口缓存。SDK目录里至少要有三块platforms/android-XX、build-tools/XX.X.X、platform-tools/adb。ANT打包会先读project.properties里的target再去platforms找对应android.jaraapt从build-tools里找。如果build-tools只有最新版而旧ant脚本按固定目录名找就会报aapt not found。最稳妥的做法是保留一套与工程年代接近的build-tools不要只留最新。NDK这边Cocos工程通常在jni/Android.mk里写APP_PLATFORM和APP_ABI。NDK版本过高时旧Android.mk里的APP_STL或toolchain路径可能变化报错会指向ndk-build内部脚本。遇到这种报错先看jni/Application.mk里的APP_ABI是否包含armeabi-v7a再看NDK版本是否比工程预期新太多。不要直接改NDK内部脚本换一套匹配的NDK比改脚本省时间。2.3 ANT的安装与build.xml结构ANT安装本身很简单下载binary包解压设ANT_HOME把bin加进PATH。验证用ant -version能输出版本号即可。真正要看的是工程里的build.xml它决定了ant clean debug和ant release到底做了什么。进到Cocos构建出来的android工程目录常见路径是build/jsb-default/frameworks/runtime-src/proj.android目录里会有build.xml、local.properties、project.properties、AndroidManifest.xml、jni/、res/、src/。先跑cd build/jsb-default/frameworks/runtime-src/proj.android ant -pant -p会列出当前build.xml里可用的target。正常能看到clean、debug、release、install、uninstall这些。如果只看到clean没有debug说明build.xml没有正确引入SDK的ant构建脚本或者local.properties里的sdk.dir没写对。ant -p还有一个用处它会提前解析import如果import路径错了这里就会报不用等到编译阶段。Cocos的build.xml一般会做几件事引入SDK的tools/ant/build.xml设置source.dir、resource.dir、assets.dir再定义-pre-build、-post-build这类hook。debug和release的真正逻辑在SDK的ant脚本里工程里的build.xml只是把路径和属性喂进去。所以排错时不要只盯着工程build.xml要看它import的那个文件是否存在。下面这条命令用来确认build.xml引用的SDK路径是否真实存在路径从local.properties里读# 打印sdk.dir并检查目录是否存在 grep ^sdk.dir local.properties SDK_DIR$(grep ^sdk.dir local.properties | cut -d -f2) test -d $SDK_DIR echo SDK目录存在 || echo SDK目录不存在这段脚本先读local.properties里的sdk.dir再用test -d判断目录。cut -d -f2只适合路径里没有等号的情况如果Windows路径带盘符比如D:/work/sdk也能正常截出来。判断结果为“不存在”时不要继续跑ant先把路径改成真实SDK目录。local.properties是本地文件不应该提交到版本库团队里每个人自己配。ant -p通过之后先跑一次ant clean debug不要直接上release。debug包能出来说明JDK、SDK、ANT、工程结构四层都通了release再出问题范围就缩小到签名和混淆。这个顺序能省很多时间也是我处理老工程时固定的第一步。3. 工程改造从Cocos构建目录到ANT可编译结构3.1 Cocos构建产物里的android目录拆解Cocos构建出来的android目录不是随便放的每个文件在ANT打包里都有明确角色。先把这个目录拆开看后面改配置才知道动哪里。下面这张表按“文件/目录 → 作用 → 是否常改”列文件或目录作用是否常改build.xmlANT入口import SDK构建脚本少改除非加自定义targetlocal.properties本机SDK路径每台机器改project.propertiestarget、build-tools、library引用常改targetAndroidManifest.xml包名、版本、权限、渠道meta-data常改ant.propertiesrelease签名参数出release必改jni/Android.mknative模块编译规则加so时改jni/Application.mkABI、STL、平台版本常看assets/Cocos资源与脚本构建时生成libs/第三方jar或so按需放res/图标、启动图、XML资源常改src/Java源码与包目录改包名时同步build.xml是入口不要轻易重写。它里面通常有一行import file${sdk.dir}/tools/ant/build.xml这一行决定了debug和releasetarget从哪来。local.properties只放本机路径换机器就要改。project.properties里的targetandroid-XX必须和SDK里platforms目录对上sdk.buildtoolsXX.X.X要和build-tools目录对上。AndroidManifest.xml里的package是Java包名不是应用显示名改它要同步改src/下的目录结构否则R文件找不到。jni/Application.mk里常见的是APP_ABI : armeabi-v7a arm64-v8a和APP_PLATFORM : android-XX。如果只出armeabi-v7a新设备安装可能没问题但部分应用市场会要求64位包如果加了arm64-v8a要确认Cocos的so和第三方so都有对应架构。缺架构的典型现象是安装成功但启动闪退日志里报UnsatisfiedLinkError说找不到某个so。这个问题在打包阶段不一定报要到安装后才暴露所以出包前要检查libs/和assets/里的so架构。res/和assets/的边界也要分清res/是Android资源走aapt编译文件名只能小写字母、数字、下划线assets/是原样打包Cocos的脚本和资源通常在这里。把中文名或大写文件名放进res/aapt会直接报错日志里会写非法资源名。这个坑在替换图标时最常见。3.2 local.properties与project.properties怎么写local.properties只写SDK路径格式是keyvalue不要加引号。Windows下用正斜杠或双反斜杠单反斜杠会被当转义。下面是一个示例# local.properties只放本机路径不提交 sdk.dir/opt/dev/android-sdk如果路径是Windows的D:\work\android-sdk写成sdk.dirD:/work/android-sdk或sdk.dirD:\\work\\android-sdk。写成sdk.dirD:\work\android-sdk时\w和\a可能被当转义导致路径变成乱码。这个文件不需要ndk.dirNDK走环境变量NDK_ROOT更稳如果工程build.xml明确读ndk.dir再补一行。project.properties管的是编译目标常用项如下# 编译目标必须与SDK/platforms/android-XX一致 targetandroid-28 # 指定build-tools版本必须与SDK/build-tools目录名一致 sdk.buildtools28.0.3 # 如果有Android Library依赖按序号写 # android.library.reference.1../library-demotargetandroid-28不是随便写的它要和platforms/android-28目录对应。如果SDK里只有android-30这里写28就会报Failed to resolve target。sdk.buildtools28.0.3要和build-tools/28.0.3对应目录名差一个小版本都会找不到aapt。这两个值改完跑ant clean debug如果还报target错误就用ls $ANDROID_SDK_ROOT/platforms和ls $ANDROID_SDK_ROOT/build-tools核对目录名不要凭记忆写。project.properties里如果引用了library路径是相对当前工程的。library工程也要有project.properties和AndroidManifest.xml否则ANT会在合并资源时失败。老工程里常见的android.library.reference.1../frameworks/cocos2d-x/cocos/platform/android/java就是这种写法。路径不对时报错会指向resolve library不会直接说路径错要看它打印的绝对路径。3.3 用ANT命令行完成debug/release打包配置齐了之后打包命令本身很短。日常先跑debug确认工程能编译cd build/jsb-default/frameworks/runtime-src/proj.android # 清理旧产物再打debug包 ant clean debug # 查看产物 ls -lh bin/*.apkant clean debug会先删bin/和gen/再走资源编译、Java编译、dex、打包、签名debug签名。产物通常在bin/下文件名包含debug或-debug.apk。如果bin/没有apk先看日志最后是不是BUILD SUCCESSFUL如果是BUILD FAILED往上找第一个error不要从最后一行倒着看最后一行经常只是“总失败”。release包的命令是# 打release包签名参数从ant.properties读取 ant clean release # 如果build.xml支持属性传入可以覆盖版本号等 ant -DversionCode102 -DversionName1.0.2 clean releaseant clean release和debug的区别在于release会走签名、可能走混淆、默认不插入debuggable。签名参数没配时有的工程会产出-unsigned.apk有的直接失败取决于build.xml里的target。-DversionCode102这种写法能不能生效要看build.xml里有没有用${versionCode}接收没有接收就不要传传了也不会改Manifest。想确认某个属性是否生效可以在build.xml里临时加一行echo messageversionCode${versionCode}/跑一次看输出。出包后不要只看文件存在先跑一次aapt dump badging看包名和版本号具体命令放在最后一章。ANT打包的产物名有时带渠道后缀有时是固定名复制到发布目录时按package和versionCode重命名不要按时间戳否则渠道多了容易混。注意ant clean会删掉bin/和gen/如果工程里有手动放进bin/的so或jar会被一起删掉。第三方文件放libs/不要放bin/。4. 签名与渠道release包、keystore和AndroidManifest的联动4.1 keystore生成与ant.properties签名参数release包必须签名ANT读签名的位置通常是工程根目录的ant.properties。先准备keystore用JDK自带的keytool生成# 生成release keystore有效期按需调整 keytool -genkeypair -v \ -keystore release.keystore \ -alias demoalias \ -keyalg RSA \ -keysize 2048 \ -validity 36500 \ -storepass changeit123 \ -keypass changeit123 \ -dname CNDemo, OUDev, ODemo, LCity, STState, CCN-keystore是输出文件名-alias是别名后面ant.properties里要一致。-keyalg RSA -keysize 2048是常见组合-validity 36500大约100年避免过期后无法覆盖安装。-storepass和-keypass在JDK 8下可以不同但很多ANT脚本默认两者相同建议先设成一样减少变量。-dname里的字段可以按需改不要包含真实个人信息用演示值即可。生成后验证别名keytool -list -v -keystore release.keystore -storepass changeit123输出里能看到Alias name和Valid from确认别名和有效期。然后把签名参数写进ant.properties# ant.propertiesrelease签名参数 key.storerelease.keystore key.store.passwordchangeit123 key.aliasdemoalias key.alias.passwordchangeit123key.store可以是相对路径相对的是proj.android目录如果keystore放在工程外用绝对路径更稳。密码里如果包含#、、:在properties文件里要转义或换密码不然会被截断。这个文件包含密码不要提交到公开仓库CI里用变量注入。签名配置好后跑ant clean release产物应该是已签名apk。验证签名用jarsigner -verify -verbose -certs bin/*-release.apk输出里出现jar verified才算签名有效。如果报no manifest或certificate chain先确认ant.properties里的别名和密码再确认build.xml的release target是否真的读了这些属性。有的工程把签名target写在自定义-post-build里属性名可能不是key.store要看build.xml里的sign任务。4.2 AndroidManifest.xml里的包名、版本号与权限AndroidManifest.xml是ANT打包时合并资源、生成R文件的依据。最常改的是package、versionCode、versionName、uses-sdk和权限。下面是一个片段示例manifest xmlns:androidhttp://schemas.android.com/apk/res/android packagecom.demo.game android:versionCode101 android:versionName1.0.1 uses-sdk android:minSdkVersion19 android:targetSdkVersion28 / uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / application android:labelDemoGame android:icondrawable/icon meta-data android:nameCHANNEL android:valuedefault / /application /manifestpackagecom.demo.game决定Java包名也决定R文件路径。改包名时src/下要有com/demo/game/目录里面Java文件的package声明也要同步改然后ant clean。只改Manifest不改src编译会报package R does not exist或cannot find symbol。versionCode是整数升级必须递增versionName是显示给用户看的字符串。uses-sdk的minSdkVersion不要低于Cocos引擎和第三方so的要求targetSdkVersion要与project.properties的target协调但不必完全相同。权限按实际功能加不要从旧工程整段复制。ANT打包不会帮你剔除未使用权限多出来的权限会在应用市场审核时被问。meta-data里的CHANNEL是渠道标记值在打包脚本里替换。application的label和icon最好用资源引用不要写死中文避免编码问题。改完Manifest后一定要ant clean因为R.java在gen/里Manifest里的包名或资源引用变了旧R.java不会自动失效。只跑ant debug有时会用到缓存出现“明明改了却还是旧包名”的玄学现象clean一次就正常。4.3 多渠道打包的ANT循环写法多渠道最稳的做法不是改包名而是把渠道号写进meta-data包名保持一致。这样R文件和src都不用动风险最低。下面用Python脚本替换Manifest里的渠道值再循环调用ANTimport re import subprocess from pathlib import Path manifest Path(AndroidManifest.xml) original manifest.read_text(encodingutf-8) channels [default, channel_a, channel_b] for ch in channels: # 只替换 CHANNEL 这个 meta-data 的 value pattern r(meta-data\sandroid:nameCHANNEL\sandroid:value)[^]*() replaced re.sub(pattern, r\g1 ch r\g2, original) manifest.write_text(replaced, encodingutf-8) # 每次 clean避免资源缓存串渠道 subprocess.run([ant, clean, release], checkTrue) # 复制产物按渠道命名 for apk in Path(bin).glob(*.apk): target Path(../out) / fdemo-{ch}.apk target.parent.mkdir(parentsTrue, exist_okTrue) target.write_bytes(apk.read_bytes()) break # 还原Manifest避免污染工作区 manifest.write_text(original, encodingutf-8)这段脚本的逻辑是读原始Manifest循环渠道列表用正则只替换CHANNEL的android:value然后ant clean release把bin/下第一个apk复制到../out/并按渠道命名最后还原Manifest。checkTrue让ANT失败时直接抛异常不会继续复制旧包。break只取第一个apk前提是bin/里只有一个release产物如果工程同时产出多个apk要按文件名过滤。如果业务确实要求不同包名比如马甲包那就不是只改Manifest了要改package、移动src/下的包目录、改所有Java文件的package声明、清gen/再打包。这个流程容易漏改建议用脚本做全量替换并在打包后跑aapt dump badging核对包名。多包名场景下不要复用同一个R文件缓存每次都要ant clean。渠道循环里还有一个细节ant.properties里的签名配置对所有渠道共用如果不同渠道用不同签名要在循环里切换ant.properties或传-Dkey.store...。传参前确认build.xml里的签名任务读的是哪个属性名不要凭猜测传。5. 避坑排查ANT安卓打包最常见的五类翻车5.1 现象aapt not found现象很直接ant clean debug跑到资源编译阶段日志里出现aapt: not found或Execute failed: java.io.IOException: Cannot run program aapt。有时前面还会打印build-tools路径但那个路径下没有aapt可执行文件。原因通常有两个一是project.properties里的sdk.buildtools写了一个SDK里不存在的版本ANT按这个版本拼路径拼出来的目录是空的二是只装了最新build-tools旧ant脚本按固定目录名找找不到。Windows下还有第三种aapt.exe存在但路径里有空格ANT没有加引号执行时被截断。解决时先列目录核对ls $ANDROID_SDK_ROOT/build-tools grep sdk.buildtools project.properties把project.properties里的版本改成ls结果里真实存在的目录名再跑ant clean debug。如果目录名对但仍然找不到检查build-tools/版本/下有没有aapt或aapt.exe有的SDK安装器只装了一半。Windows路径有空格时把SDK移到无空格目录比如D:/android-sdk不要放在C:/Program Files/...下面。5.2 现象Source option 6 is no longer supported现象是Java编译阶段失败日志里写Source option 6 is no longer supported. Use 8 or later后面跟着javac任务和build.xml行号。工程代码可能一行没改换了一台机器就报。原因是这台机器上的JDK不是8可能是11或17。旧SDK的ant脚本默认source1.6新JDK不再支持。ANT只是调用者改ANT版本没用。解决分两步先确认java -version和javac -version都是8并且JAVA_HOME指向JDK 8如果机器上必须保留高版本JDK就给这个工程单独配一个终端环境把JAVA_HOME临时指到JDK 8。改build.xml里的source和target到1.8也能过编译但会影响所有引用这个build.xml的工程不如切JDK干净。切完JDK后记得ant clean旧gen/里的class可能是高版本JDK编的。5.3 现象ndk-build 报 APP_PLATFORM 或 toolchain 错误现象是-pre-build阶段调用ndk-build失败日志里出现Android NDK: APP_PLATFORM android-XX is not supported或toolchains/.../prebuilt路径不存在。Java层还没开始编译就停了。原因是NDK版本和工程里的jni/Application.mk不匹配。旧工程写APP_PLATFORM : android-9新NDK可能最低只支持android-16或更高旧工程写APP_STL : gnustl_static新NDK已经移除gnustl。反过来NDK太旧也会不认新ABI。解决时先看jni/Application.mkcat jni/Application.mk把APP_PLATFORM改到NDK支持的最低版本把APP_STL改成c_static或c_shared按第三方so的依赖选再跑ndk-build clean和ant clean debug。如果工程依赖的第三方so是用gnustl编的不要单独换STL要么找对应版本NDK要么让第三方库重新出包。改完Application.mk后libs/下的旧so要先删避免新旧ABI混在一起。5.4 现象签名后安装解析失败现象是ant release显示成功bin/下有apk但安装时报“解析包时出现问题”或“应用未安装”。用jarsigner -verify可能显示已签名但安装就是不过。原因常见三种ant.properties里的key.alias和keystore里的别名不一致key.store.password和key.alias.password写反AndroidManifest.xml里的package和R文件包名不一致导致apk内部结构损坏。还有一种少见情况versionCode不是整数或者uses-sdk的minSdkVersion高于设备系统版本。排查顺序先keytool -list确认别名再jarsigner -verify确认签名最后aapt dump badging看package和versionCode。如果签名有效但安装失败重点看aapt dump badging输出的包名是否和预期一致。包名不对时回到Manifest和src/目录同步修改ant clean后重打。密码写反时日志不一定报错因为签名任务可能用了空密码或默认值产物看起来有签名但实际上不完整。提示ant.properties里的密码不要用#开头properties文件会把#当注释。密码里带等号时用\转义或者直接换一个不含特殊字符的密码。5.5 现象路径带空格或中文导致构建中断现象是构建到一半报Cannot run program、The system cannot find the path specified或者aapt报某个资源文件不存在但文件明明在。日志里的路径被截成两段或者中文变成乱码。原因是ANT和旧SDK脚本对路径分隔符、空格、编码处理不完整。工程放在D:/工作/demo game/这种路径下空格会把demo game拆开中文在Windows控制台编码下可能变成问号。local.properties里的反斜杠也会被当转义。解决时把工程和SDK都移到无空格、无中文的路径比如D:/work/demo和D:/work/android-sdk。local.properties里的路径统一用正斜杠。Windows控制台如果还有中文乱码在跑ANT前执行chcp 65001切到UTF-8或者把ANT_OPTS加上-Dfile.encodingUTF-8。改完路径后删掉bin/和gen/重新ant clean debug不要用旧产物覆盖。6. 验证与提速从apk反查配置到增量打包的固定手法6.1 用aapt dump badging验证包出包后不要只看文件名先用aapt dump badging反查apk内部信息AAPT$ANDROID_SDK_ROOT/build-tools/28.0.3/aapt $AAPT dump badging bin/demo-release.apk | head -n 20输出里重点看package: namecom.demo.game versionCode101 versionName1.0.1、launchable-activity、native-code: armeabi-v7a arm64-v8a。包名和版本号对不上说明Manifest被改错或用了旧包native-code缺架构说明jni/Application.mk或libs/里的so不全。launchable-activity不对安装后桌面可能没有图标。6.2 ANT增量与clean的取舍ANT的debugtarget会按时间戳跳过未变文件日常改Java代码可以增量但改AndroidManifest.xml、project.properties、res/资源名、签名配置后必须ant clean。我习惯是本地联调ant debug出渠道包和release包一律ant clean release。clean多花几十秒能避免“改了没生效”的假象。下面这张表是取舍依据场景命令原因只改Java逻辑ant debug增量编译快改Manifest包名/权限ant clean debugR.java和合并资源要重建改签名配置ant clean release避免旧签名产物混入出渠道包ant clean release防止渠道资源串包6.3 一个固定检查清单每次出包前按这张表过一遍比出事后再翻日志省时间检查项命令或位置通过标准JDK版本java -version1.8.xANT可用ant -version输出版本号SDK路径local.propertiessdk.dir目录存在编译目标project.propertiestarget与platforms目录一致签名参数ant.properties别名、密码与keystore一致包名版本aapt dump badgingpackage/versionCode符合预期so架构unzip -l apkgrep lib血泪经验是ANT打包的坑大多不在代码而在“以为改过了”。从那以后我每次出release包都强制走一遍ant clean release再用aapt dump badging核对包名、版本号和so架构最后才把apk放进发布目录。这套配置模板和检查表我放在工程根目录的tools/ant-android/下拿到后先对照第2章的目录树核一遍路径再改local.properties和ant.properties两个文件基本能少走一半弯路。希望帮到你。本文还有配套的精品资源点击获取