安卓修改大师智改工坊 · 实战笔记
一个人,一台 Windows 笔记本,一条改包流水线
客户签过字的授权说明、一个待改的 APK、一份说清楚的需求,这就是我全部的“产能”。智能修改电脑版把中间的脏活串了起来:导入、话术与附件、AI 修改、自动打包、装机预览、存档交付,一步接一步,不用我在六个窗口之间找刚才的思路。
只需说话,就能让应用变成你想要的样子。
了解智能修改电脑版与下载页 →
上周二晚上九点,一个做仓储的老客户发来消息:内部盘点工具要换新图标,应用名加上“内测”两个字,版本号从 1.4.2 提到 1.5.0,启动页底部加一行“仅限内部使用”。他补了一句:版权是我们的,开发团队也同意改,授权书明天盖章发你。
这种单子金额不大,但特别典型:改动点碎、沟通轮次多、交付标准还模糊。以前我接到这种消息,第一反应不是打开工程,而是先叹气——因为接下来两个小时,我要在五六个窗口之间来回跳,真正动手的时间可能只有二十分钟,剩下的都花在“找回刚才那一步”上。
改包这件事,难的从来不是某一个命令,而是命令之间的衔接:包在哪、图标放哪层、上次用的哪个签名、客户说的“内测”是全角还是半角。每一次窗口切换,都是一次上下文重建。
一个人接改包单,真正被吃掉的是上下文
我把以前接一单的固定动作写在便签上,数了数,一共十一步。每一步都不难,难的是它们分散在不同程序里,而且顺序不能乱。
- 打开存放 APK 的文件夹,确认客户发来的是不是最终包;
- 启动 apktool,敲反编译命令,等日志刷完;
- 去 res 下找 mipmap 的五六个密度目录,逐个替换图标;
- 改 strings 里的应用名,改 apktool 配置里的版本号;
- 回编、对齐、签名,三条命令一步都不能省;
- 签名口令从密码管理器里复制,粘错一次从头再来;
- adb 装包,再拉起启动页,看有没有闪退;
- 客户说桌面图标没变,再解释启动器缓存,卸载重装;
- 截图发群,等一句“可以了”;
- 把包、日志、说明整理进一个文件夹,命名、压缩;
- 发网盘链接,等客户下载,再补一句“装之前先卸载旧版”。
你看,没有一步需要高深技术,但每一步都在制造切换。反编译窗口、资源管理器、命令行、密码管理器、手机投屏、聊天窗口,六个地方来回看。真正让人累的不是手速,是每次切回来都要重新确认:我刚才改的是哪个包?这个 mipmap 目录是 xxhdpi 还是 xxxhdpi?上一次签的是哪个 keystore?
后来我把流程换成了智能修改电脑版的一条线:导入 → 话术与附件 → AI 修改 → 自动打包 → 装机预览 → 存档交付。注意,重点不是“每一步快了多少”,而是原来十一步里那些必须由人接力传递的状态,现在被放在同一个项目上下文里。包是同一个包,历史是同一份历史,日志是同一份日志。
| 环节 |
以前 |
现在的流水线 |
真正省掉的 |
| 确认包 |
解压看清单,翻聊天记录对版本 |
拖入即显示应用名、包名、版本、启动页 |
不用先反编译再确认 |
| 交代需求 |
写三段文字,再发一个图标压缩包 |
话术点选,附件逐条写用途 |
客户不用猜图放在哪 |
| 等修改 |
盯命令行,切窗口看进度 |
AI 工作区执行,完成留标记,主窗自动接打包 |
不用守着进度条 |
| 打包签名 |
三条命令加口令,顺序错了重来 |
四步自动执行,最后 verify 出证书信息 |
不会漏对齐,也不会签了个寂寞 |
| 装机验收 |
adb 两条命令,再手动截图 |
自动安装、自动拉起、复核前台应用 |
客户当场看到效果 |
| 归档 |
手动建文件夹、改名字、压缩 |
项目目录与 pack.log 原样保留 |
出问题能回查,不靠记忆 |
一台电脑、一个项目目录、一份授权说明,就能组成最小可交付的改包工作台。
把返工拆开看,原因无非三类:包拿错、需求理解错、签名或安装环境不对。流水线分别用 aapt、附件说明、verify 加装机预览去挡。它不能保证一次成功,但能让失败发生在你还在电脑前的时候,而不是客户已经装到手机上之后。
入口这一关:拖进 APK,aapt 先把底细说清楚
接单最怕的不是改不动,而是改错包。客户群里经常同时躺着“最终版”“最终版2”“最终版-真的最终”三个文件,文件名一样、大小差不多,打开才知道哪个是带新接口的。所以我把“确认包”放在流水线第一环,而且要在动手之前完成。
智能修改电脑版支持导入 APK、JAR、APKS、XAPK、APKM、CLASS 这几类文件。实际接单时格式比想象中杂:有人发 XAPK(带 OBB 数据),有人发 APKS(拆分包),还有人把 JAR 当 APK 发过来。以前要先回一句“你这个不是标准 APK”,再教对方怎么导出;现在直接拖进窗口,工具会按类型处理,少了一轮解释。
导入后第一眼看到的是 aapt 解析出来的信息:图标、应用名、包名、版本号、目标 SDK、启动页。别小看这一屏,它把“确认包”从反编译之后提前到了反编译之前。你不需要等 apktool 跑完、再去翻 AndroidManifest,拖进来的那一秒就能判断:这是不是客户说的 1.4.2,启动页是不是他截图里的那个 Activity。
图标解析有个容易踩的坑,值得单独说。APK 里的图标通常有 mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi 好几套,换图标时如果只替换其中一套,在某些机型上桌面还是旧图。电脑版取最高密度那张原图作为展示和替换基准,这个逻辑听起来简单,但实现时有个陷阱:aapt 输出里的密度值 65534 表示“任意密度”(anydpi),它不是最高密度。如果按数值大小排序取最大,会把自适应图标的 XML 当成最高清位图,换完在 Android 8 以上还是旧样子。正确做法是先排除 65534,再比较真实密度。很多换图标教程就栽在这里,读者照做一遍,回来骂工具不行。
项目落盘的结构也值得知道。每个项目在 Project 下有一个 8 位随机目录,里面写 config.ini 和 history.ini,并复制一份 source.apk。反编译在 apktool 子目录里进行,输出 apktool.log。随机目录的好处是同一客户的多个版本不会互相覆盖;代价是不能靠目录名认项目,得看详情页的应用名和版本。我一般会在交付时把“项目目录 + 客户名 + 日期”记在台账里,后面找起来快。
反编译速度方面,12 MB 左右的包实测约 3 秒完成。这个数字不是重点,重点是与它配套的超时:超过 10 分钟会中断并报错。加固包、资源异常的包,apktool 有时会卡在某个循环里;以前我能盯着屏幕等半小时,现在十分钟就明确失败,可以去和客户沟通“这个包需要先脱壳或拿未加固版本”,而不是无限期地等。
接单检查清单
- 应用名、包名与客户描述一致;
- 版本号是客户要改的那一版,不是上一版;
- 启动页 Activity 与截图对得上;
- 授权说明与包名一一对应,避免拿错授权;
- 原包另存一份,任何时候都能回到起点。
先看清包名、版本和启动页,再决定怎么改,能省掉一大半返工。
把需求说成人话:3000 条话术与“附件直给”
需求描述是改包流程里最容易被低估的一环。客户说“图标换一下”,到底换哪张、换几档、圆角要不要保留?客户说“名字改一下”,是改桌面显示名,还是连关于页面里的名字一起改?以前我靠追问,一个问题一个问题确认,客户烦,我也烦。
电脑版的详情页给了一个输入框,右侧是 3000 条话术,分成 6 类,每类 500 条:界面美化、弹窗引流、去除限制、常规修改、混淆去毒、插件添加。点一条,内容就填进输入框,然后你可以按自己的项目改。它的价值不是让你偷懒照抄,而是解决“对着空白框不知道从哪写”的问题。比如“把启动页背景换成附件里的图,底部加一行小字”,这句话我就是从“界面美化”里点了一条,再把附件编号补进去。
比话术更关键的是附件直给。图标、启动图、字体、配置文件都是二进制,文字描述再准也不如把文件递过去。附件区支持一次多选,但每个文件必须写用途,而且至少 10 个字;提交前会校验文件存在、不是目录、不是 0 字节、可读。拼装时按“序号 + 路径 + 说明”的格式跟需求一起发出去,history.ini 只保留用户原话,不保存拼装后的长文本。
为什么要强制写用途?因为同一个项目里可能同时有商店图、桌面图、启动页背景三张图,尺寸和用途完全不同。附件说明写“桌面图标源图,请生成五档密度”和“启动页背景,冷启动第一帧使用”,AI 才知道哪张该缩放、哪张该原样放。这个约束看起来是麻烦,实际上是把你脑子里的隐含信息显式化,减少来回。
附件写法示例
- 01_icon_1024.png:桌面图标源图,请生成 mdpi 到 xxxhdpi 五档,保留透明边;
- 02_splash_1080x1920.jpg:启动页背景,冷启动第一帧铺满,不裁切主体;
- 03_auth_scan.pdf:客户授权说明扫描件,仅用于本次内部版本,不随包分发。
历史记录的设计也在为“少切换”服务。详情页的历史最新在上,保留完整原文,右侧有“选择”可以回填到输入框。同一个需求要出第二版时,不用重新组织语言,点“选择”,改两个词,再补一张新图。改包接单里大量工作是“上一版再加一点”,这个回填动作省掉的是重新描述需求的十分钟,以及描述不一致带来的返工。
附件直给不只用于图片。给内部工具换 API 地址时,我把 config 文件作为附件挂上,用途写“内网正式环境地址配置,仅替换 host 与端口,不改其他字段”。这种需求用文字描述最容易出歧义:测试环境是 test 开头,正式环境是内网 IP,客户自己也说不清该换哪一行。文件递过去,再写清边界,AI 改完我对比一眼就能确认只动了该动的地方。
顺便说一句,项目列表能看历史、能删除项目,但删除只允许 Project 的直接子目录。这个限制看起来保守,实际是防止误删整个工作区或者把工具目录当项目删掉。接单的人最怕手滑,这种“只允许在边界内删除”的设计,比弹十个确认框都管用。
点下“立刻修改”:ai_done.flag 让打包自己发生
需求写完、附件挂好,接下来就是点“立刻修改”。这一下点击背后发生了三件事:你输入的原文连同日期写进 history.ini;需求被送进右侧的 AI 工作区执行;主窗口开始等一个信号。
这个信号不是弹窗,也不是接口回调,而是一个文件:AI 改完项目后,在项目目录里留下 ai_done.flag。主窗口每 2 秒轮询一次,读到这个文件就把它删掉,然后自动进入打包。等待上限是 1 小时,超时就不再干等。
第一次看到这个设计,我觉得土:都什么年代了,还用文件当信号?用久了才发现它解决的是真问题。AI 工作区负责改工程,主窗口负责打包装机,两边各管一段。它们之间如果靠内存共享或者私有接口,任何一方崩溃,另一方都可能永远等下去,或者收到一个半截的状态。文件信号简单、可观察、可恢复:AI 正常结束就留文件,主窗口读到就继续;AI 崩了就没有文件,主窗口一小时后超时;主窗口没开,文件就留在那里,下次打开还能看到。
一次点击之后的真实时序
- 原文与日期写入 history.ini,后面回填、对账都靠它;
- 需求送进右侧 AI 工作区,开始改 apktool 工程;
- AI 完成后在项目目录写入 ai_done.flag;
- 主窗口每 2 秒轮询,读到标记立即删除,避免重复触发;
- 自动执行四步打包,再走 adb 装机预览;
- 全过程写入 pack.log,交付时随包归档。
“读到即删”这个动作也很关键。如果只是检测文件存在,那么上一次的标记会一直留着,下一次点“立刻修改”可能还没改完就触发打包,打出一个半成品。删除之后,标记只代表“这一次刚完成”,状态是干净的。工程里这种小动作,比写一堆注释有用。
这一环真正省掉的是什么?是“守着”。以前我点完修改,要盯着命令行,看到反编译结束、看到回编成功,再手动敲打包命令。中间只要去回一条客户消息,回来就得翻日志找进度。现在我可以点完就去写另一单的报价、回另一个客户的问题,听到打包完成的提示再回来。时间没有被压缩多少,但注意力被释放了,这在一个人接单的场景里比速度值钱。
当然,异步也有代价:你得知道去哪看状态。我的习惯是点完之后瞄一眼项目目录,确认 ai_done.flag 还没出现;如果过了很久还没有,就去右侧工作区看它是不是卡在某个大资源上。超时 1 小时的设计也提醒我:这不是无限期的后台任务,遇到加固包或者异常资源,及时止损,换包或者换方案。
还有一个使用习惯:标记没出现时,先别急着重复点。看项目目录里 apktool 的时间戳有没有变化,翻一眼 apktool.log 的最后几行,再确认右侧工作区是不是还在跑。重复点会写两条历史,也可能让两个修改任务同时动同一份工程,反而更难查。流水线把等待变成可见状态,但判断仍然要人来做,这是我一直提醒自己的地方。
四步打包与 verify:签名不是按一下,是要能自证
自动打包听起来像“一个按钮”,实际是四步,顺序固定,少一步都不算完成。电脑版把它做成流水线,但每一步用的还是标准工具,日志里都能查到。
apktool b -f -o build\unsigned.apk
zipalign -f -p 4 build\unsigned.apk build\aligned.apk
apksigner sign --ks ... build\aligned.apk
apksigner verify --print-certs build\aligned.apk
第一步回编,-f 强制重建,-o 指定输出,产物先叫 unsigned.apk,名字就把状态说清楚了:还没签名,不能直接装。第二步对齐,4 字节对齐是 Android 加载未压缩资源的硬要求,-p 让共享库按页对齐,减少安装后的加载开销。第三步签名,按项目设置选择默认签名、JKS/keystore、PEM+PK8 或随机签名,签名方案支持 v1、v2、v3、v4,默认 v1+v2+v3。第四步 verify,打印证书信息,确认“到底签没签上”。
为什么非要多一步 verify?因为签名失败有时候不吵不闹。密钥格式不对、别名不对、口令不对,前面的步骤可能看起来跑完了,产物也在,但签名根本没写进去;还有些情况下签名块写了,证书链却不完整。apksigner verify --print-certs 会把证书主题、指纹、签名方案逐项打出来,格式错误也只有这一步会明确报出。没有 verify 的打包,等于闭着眼睛交付。
四步的顺序也不能乱。zipalign 必须放在签名之前,因为 v2 签名覆盖的是整个文件的字节;你先签名再对齐,对齐会改动文件内容,签名立刻失效。很多“装不上、提示未安装”的包,就是顺序错了。电脑版把顺序写死在流程里,不给人犯错的机会,这比在文档里写三行警告有效。
| 步骤 |
做什么 |
常见失败 |
怎么确认 |
| 回编 |
apktool 重建未签名包 |
资源引用缺失、smali 语法错 |
看 apktool.log 是否正常结束、build 目录是否生成产物 |
| 对齐 |
zipalign 4 字节对齐,共享库按页对齐 |
输入文件不存在、路径含空格未引号 |
命令返回 0,产物体积正常 |
| 签名 |
按四种密钥方式之一写入签名 |
别名错、口令错、PEM 与 PK8 不配对 |
verify 通过,证书指纹与预期一致 |
| 校验 |
verify --print-certs 打出证书 |
签名方案不兼容目标系统 |
v1/v2/v3 逐项显示,无 WARNING |
签名方案的选择也要看交付对象。默认 v1+v2+v3 覆盖了从旧机型到新系统的大部分场景;v1 是 JAR 签名,兼容老系统;v2 是整文件签名,校验更快、防篡改更强;v3 支持密钥轮换,为将来换证书留余地;v4 主要用于增量安装,需要配套的安装方式,不是所有 adb 版本都吃。给客户交付内部工具时,我一般保持默认,除非客户明确要求只签某一种。
口令的处理是我最在意的细节之一。签名口令走环境变量,不拼进命令行,也不写进日志。原因很现实:命令行参数在进程列表里可见,日志文件会被打包发给客户。一个 keystore 的口令泄露,意味着别人可以签出和你一样的包,客户的内测渠道就可能被顶掉。工具把口令从日志里拿掉,是底线,不是加分项。
验收时我一定会看的三件事
- verify 输出里的证书指纹,和客户归档的签名证书是否同源;
- pack.log 里四步是否齐全,有没有跳过 verify;
- 产物是不是 build 目录下最新时间戳的那个,别发错包。
打包日志不是给人看的仪式感,而是交付出问题时唯一能回查的证据链。
adb 装机预览:交付标准是“能在客户手机上打开”
改完包、签完名,还不算交付。客户不关心你的 verify 输出,他关心的是装到手机上,图标对不对、名字对不对、点开会不会闪退、启动页有没有换。所以电脑版在打包完成后会自动走一遍 adb:找设备、装包、拉起启动页,再用系统状态复核前台应用。
拉起用的是 am start -W -n 包名/Activity,-W 表示等待启动完成并返回结果,这样脚本能知道应用到底起没起来,而不是发完命令就当成功。这里最容易出问题的是 Activity 名字:应用名好改,启动页的类名却可能因为构建配置、别名 Activity、动态特性而变。电脑版用了三档查找:先读 config.ini 里记录的 LaunchableActivity;读不到就用 cmd package resolve-activity --brief 向设备的包管理器查询;再不行才用旧方式兜底。
这三档的顺序是有讲究的。config.ini 是导入时解析出来的,快,但可能因为改包而变化;设备查询是装包之后问系统“这个包的入口是谁”,最贴近真实;旧方式兜底是为了兼容老 adb 或特殊 ROM。以前我自己写脚本时只用第一档,结果有一次客户把启动页换成了别名 Activity,am start 直接报“Activity class does not exist”,包明明装上了,就是打不开。那种时候你会怀疑是改包改坏了,其实是启动入口找错了。
应用起来之后,还会用 dumpsys 复核前台应用。am start 返回成功不等于界面上真的是你的应用:有可能被权限弹窗挡住,有可能启动后立刻跳转到别的页面,也有可能旧版本还在后台。dumpsys 看的是系统当前聚焦的窗口和前台包名,这个复核动作能把“命令成功”和“用户看到”之间的差距补上。
手机连着的时候走 scrcpy 投屏,电脑上直接看到手机画面;模拟器则提到最前。对一个人接单来说,这个细节很重要:你不需要一边看电脑一边扭头看手机,也不需要截图发给自己再放大检查。改完的图标在桌面第几屏、应用名有没有被截断、启动页那行小字会不会被状态栏挡住,投屏里一眼就能看出来。
客户验收的语言从来不是“签名成功”,而是“我装上了,能打开,图标是我要的那个”。自动装机预览就是把这句话提前到交付之前,让你先替客户说一遍。
还有一个实际好处:装机预览会自动覆盖“卸载旧版”的沟通。Android 不允许同包名不同签名的应用直接覆盖安装,如果客户手机上装的是开发团队的正式签名版,而你用默认签名打了内测包,安装会失败。以前要解释半天,现在装的时候就能看到失败,及时改成用客户提供的 keystore,或者明确告诉客户“这个内测包需要先卸载正式版”。问题暴露在交付前,而不是客户在群里发一句“装不上”。
预览阶段我还会专门试三个动作:冷启动、按 Home 再回来、从最近任务划掉再打开。冷启动看启动页和首屏;Home 再回来看着色和状态恢复;划掉再打开看有没有残留的旧进程缓存。改启动页、改应用名这类需求,问题往往不在第一次打开,而在第二次、第三次。自动装机只负责把包装上去、拉起来,这三个动作还是要人来点,但至少不用再敲命令。
预览通过之后,我才会把包发出去。发之前会把应用名、版本号、图标、启动页四个点各截一张图,和 pack.log 一起放进交付文件夹。客户下次说“还是上一版好看”,我能立刻翻出当时那一版;客户说“版本号怎么没变”,我能指出设置里的版本号和构建时间。这些动作不产生直接收入,但能挡掉大量扯皮。
磁吸双窗口:效率来自不被打断,而不是手速
改包的时候,我需要同时看两样东西:左边是项目详情和需求,右边是 AI 工作区里正在发生的事。以前的做法是 Alt+Tab 来回切,或者把两个窗口手动拖成左右各一半。手动拖的问题是谁也对不齐:今天拖好了,明天换个分辨率又歪了;主窗口一最大化,AI 窗口被盖住;用完关掉,下次再拖一遍。
电脑版的做法是磁吸。AI 工作区打开后贴在主窗口旁边,两个窗口高度一致,看起来像同一块工作台被分成了两栏。它不是简单地把窗口挪过去,而是每次布局都重新算宽度:AI 工作区宽度等于屏幕工作区宽度乘以设定占比,再减去间隙和主窗口宽度。主窗口拉宽,AI 区域相应变窄;主窗口挪动,AI 区域跟着贴过去。屏幕分辨率变了,公式还是那一个,不会出现“右边露出一截桌面”的尴尬。
为了让吸附跟手,程序默认每 5 毫秒检查一次窗口位置。这个频率听起来夸张,但窗口拖动时的坐标变化就是这么快;如果按几百毫秒检查,用户会看到 AI 窗口一顿一顿地追。5 毫秒轮询加上轻量判断,开销很小,视觉上就是粘在一起。
难点不在“贴上去”,在“什么时候不该贴”。用户可能故意把窗口拖走,也可能只是程序自己在调整布局。如果分不清这两件事,就会出现“用户往左拖,程序往右吸”的打架。电脑版做了事件稳定判定:只有窗口静止超过设定的 SnapBackDelayMs,才算用户真的想挪动;被拖离约 260 毫秒后自动吸回。这个延迟短到几乎感觉不到,又长到不会误判一次正常拖动。
还有一个很小但很典型的坑:窗口最小化时,系统会把它挪到屏幕外,坐标可能是负几万。如果程序照着这个矩形去算布局,AI 窗口会被带到看不见的地方。电脑版对最小化产生的占位矩形整轮跳过,等窗口恢复再重新计算。dock.log 里记录的就是这些吸附和布局事件,出问题时不用猜,翻日志就能看到哪一轮算了什么。
双窗口在接单里的三个实际用法
- 左边开着需求原文和附件说明,右边看 AI 改到哪一步,不用背需求;
- 从资源管理器把新图标直接拖进主窗口,AI 区域不挡路、不闪;
- 远程会议共享屏幕时,客户能同时看到“我提的要求”和“改完的结果”。
需求、附件、执行状态同屏,减少的是来回切换,不是思考时间。
我自己的体感是,磁吸带来的不是“快”,而是“连续”。一次改包被打断三次,每次回来要花几十秒找回状态;两个窗口固定在那里,需求、附件、日志、结果都在视野里,思路不容易断。独立开发者一天要切换很多角色:接需求、改包、测试、交付、催款。能把其中一段固定成一个稳定画面,已经很有价值。
一个项目一个目录:pack.log 与可回滚的底气
接单久了,最怕的不是改不出来,而是“改出来了但说不清怎么改的”。客户三个月后说某个页面不对,你打开电脑,发现当时用的是哪个包、哪个签名、改过哪几处,全靠记忆。电脑版用最朴素的办法解决这个问题:一个项目一个目录,所有东西都留在里面。
Project\
a1b2c3d4\ 8 位随机项目目录
source.apk 原始包,只读参照
config.ini 项目配置、启动页记录
history.ini 需求原文与日期
apktool\ 反编译工程
apktool.log 反编译与回编日志
build\ 对齐、签名产物
...
source.apk 是我最看重的文件。它意味着任何一次修改都有起点:改坏了,重新导入 source.apk 开一个新项目;客户要对比,直接装原包;怀疑是原包就有问题,先用 source.apk 复现一遍。以前我把原包放在下载文件夹,改到第三版时经常找不到最初那个,只剩一堆“修改后”“修改后2”。
日志分得很细,各有各的用途。apktool.log 记反编译和回编的输出,资源缺失、smali 语法错都在这里;pack.log 记四步打包的全过程,对齐、签名、verify 的每一步和结果;error.log 记未处理异常;dock.log 记窗口吸附和布局。看起来是四个文件,实际是四条证据链:改包出错看 apktool.log,打包出错看 pack.log,程序崩了看 error.log,界面抽风看 dock.log。
pack.log 在交付时的作用尤其大。客户说“这个包签名怎么和上次不一样”,你把两次的 verify 输出并排一看,证书指纹不同,立刻能定位是换了签名方式;客户说“版本号没改”,你看回编时间和产物时间,能判断是打包用了旧产物还是安装没覆盖。没有日志,这些问题只能靠猜,猜错了就是一轮返工。
pack.log 里我重点看三样:zipalign 的返回码、apksigner sign 用了哪个证书别名、verify 打出的 v1/v2/v3 是否齐全。别名不对时,sign 可能报错也可能静默产出未签名包,verify 一跑就露馅。把这三样抄进交付说明,客户的技术对接人一看就懂,不用来回问。
工作目录的选择也考虑到了接单场景。程序会按 D → E → F → G → C 的顺序找盘,取第一个可读写且剩余空间不少于 1GB 的,然后在下面建 tools 和 Project 两个子目录。为什么是这个顺序?大多数 Windows 笔记本的 C 盘是系统盘,空间紧张;D 盘往后更可能是数据盘或移动硬盘。把反编译工程、构建产物、工具链放到数据盘,既不挤占系统盘,也方便整盘备份。
工具链的查找是递归的。你不用把 apktool、zipalign、apksigner、adb 摆成某个固定目录结构,程序会在工作目录里递归搜索。换电脑、换移动硬盘、把工具从旧目录搬到新目录,项目还能继续用。这个设计对经常在台式机和笔记本之间切换的人很友好:项目目录整个拷过去,工具路径重新指向即可。
项目多起来之后,我会在客户台账里记三列:项目目录的 8 位编号、客户与包名、最后一次交付日期。目录名是随机的,不能靠它认项目;但把编号和客户对上,找起来就很快。清理时也只删 Project 的直接子目录,一次一个,删之前先确认 source.apk 和最终包已经归档到交付盘。
参数设置里还有几项看着小、用起来顺的功能:工作目录、十套配色主题、工具链体检、首页提示条开关。主题有极夜蓝、深海蓝、紫罗兰、樱花粉、烈焰红、落日橙、古铜金、青柠绿、薄荷绿、石墨灰,长时间盯日志的人可以选低对比度的深色系;工具链体检在换机、升级系统之后先跑一遍,省得改到一半才发现 apksigner 找不到;首页提示条开关则是给熟练用户减少干扰。
顺便交代运行环境:Windows 10/11 64 位,.NET Framework 4.6.2 及以上,安装包约 6.86 MB。对一个人接单来说,这意味着不用为了改一个包专门换机器;装好之后先跑一遍工具链体检,确认 apktool、zipalign、apksigner、adb 都在,再开始接活。
我的交付归档习惯
- 项目目录原样保留,不清理 build,方便客户回头要同一版;
- pack.log 和 verify 输出单独抄一份到交付文件夹,客户不用解压项目;
- 文件命名带日期和版本号,例如 20261021_盘点助手_1.5.0-rc1;
- 授权说明与包名一起归档,下一次改动先核对授权范围;
- 超过三个月的项目只留 source.apk、pack.log 和最终包,节省空间。
删除项目的限制也值得提一句:只允许删除 Project 的直接子目录。这个规则挡掉的是“手滑选中整个 Project 目录按删除”的灾难。接单电脑上往往堆着几十个项目,清理时最容易出事;把删除范围锁死在项目目录这一层,成本很低,收益很大。
两个实例:授权内部工具换图标,自家 App 换启动页
前面讲的是流程,这一节把两个真实单子拆开看。两个案例都满足一个前提:应用归客户或我自己所有,改动范围有书面授权。没有这个前提,后面的方法都不适用。
案例一 · 客户授权的内部工具
换图标、加“内测”、提版本号
客户是一家做仓储的小公司,盘点工具由外包团队开发,版权归客户,开发团队也同意为内测版本换标识。需求有四条:桌面图标换成新 CI;应用名从“盘点助手”改成“盘点助手(内测)”;版本号从 1.4.2 提到 1.5.0-rc1;启动页底部加一行“仅限内部使用”。
以前的做法:先用 apktool 反编译,去 res 下找 mipmap-mdpi 到 mipmap-xxxhdpi 五六个目录,逐个替换图标;这个包还带自适应图标,mipmap-anydpi-v26 下有一份 XML 引用前景和背景,如果只换位图不换引用,Android 8 以上还是旧图标。然后改应用名字符串、改 apktool 配置里的版本号,回编、对齐、签名,adb 装到测试机。装完发现桌面还是旧图标,再让客户卸载重装,一来一回半天。最后打包发网盘,日志留在自己电脑里,客户问“改了什么”只能凭记忆说。
现在的做法:把包拖进智能修改电脑版,aapt 先显示应用名、包名、版本 1.4.2、启动页 Activity,和客户描述对得上,确认没拿错包。附件里放三样东西:1024 的图标源图,说明写“桌面图标源图,生成五档密度并保留自适应结构”;启动页设计稿,说明写“冷启动第一帧背景,底部小字不要被裁切”;客户授权说明扫描件,说明写“仅限本次内部版本,不随包分发”。需求从“常规修改”里点一条话术,改成“替换图标与应用名,版本号提到 1.5.0-rc1,启动页加指定小字”。点“立刻修改”,AI 改完留标记,主窗口自动打包,verify 打出证书,adb 装到测试机并拉起。
这个单子还有一个签名上的插曲。客户手机里装着开发团队签的正式版,包名相同、证书不同,直接覆盖安装会被系统拒绝。以前我会先让客户卸载,客户又担心丢数据。这次在项目里直接选客户提供的 JKS,口令走环境变量,签完 verify 打出的证书指纹和客户归档的一致,安装时顺利覆盖,本地数据也保住了。签名一致这件事,只有在装之前确认,才有意义。
怎么验证:先看桌面图标是不是新 CI,长按看应用信息里的名称和版本号;再冷启动一次,看启动页底部小字有没有被状态栏遮住;然后看 verify 输出的证书指纹,确认和客户归档的签名一致;最后把 pack.log、最终包、三张验收截图放进交付文件夹。客户在群里只回了一句“这次不用教我怎么装了”。
版本号这里也有个容易忽略的点:应用信息里显示的是 versionName,系统判断能不能覆盖升级看的是 versionCode。只改显示名不改 versionCode,某些渠道会认为新包不比旧包新。电脑版的修改范围包含 apktool 工程里的版本配置,我在需求里会明确写“versionName 1.5.0-rc1,versionCode 从 14 提到 15”,交付前在应用信息里核对显示版本,再用 dumpsys package 看 versionCode,两个都对上才算完成。
第二版来得很快:客户要把“内测”改成“内测·仓储”,版本号提到 rc2。我打开详情页,历史里点“选择”回填上次原文,改两处文字,换一张新图标,其他附件不动。这一次连需求都没重新组织,因为上下文还在项目里。
案例二 · 自家应用
换启动页、去自家开屏广告、提版本号
我自己有一个记账 App,春节前想换一版启动页:背景换成红金配色,中间保留 logo,底部去掉去年那句活动文案;顺便把自家开屏广告关掉,版本号从 3.2.0 提到 3.2.1。应用是我自己写的,签名 keystore 在我手里,改起来没有授权障碍。
以前的做法:改启动页要回 Android Studio,换 drawable 里的图,改布局,重新构建 release 包,再用 Android Studio 的签名配置打包。只改一张图,也要等 Gradle 跑完;如果手上没有完整工程,还得走 apktool 那条路,两条工具链来回切。开屏广告是自家的一段启动逻辑,改完要重新测冷启动、热启动、从后台恢复三种情况,生怕改出白屏。
现在的做法:拖入线上 release 包,aapt 确认版本 3.2.0 和启动页;附件给两张启动图,一张 1080×1920、一张 1440×2560,说明写“冷启动第一屏背景,铺满不裁切,中间留出 logo 安全区”;需求写“替换启动页背景,去掉开屏活动文案与自家开屏广告,版本号改为 3.2.1”。签名选 JKS/keystore,用我自己的证书,方案保持 v1+v2+v3。点“立刻修改”,等标记出现,自动打包,verify 通过。
怎么验证:先杀掉进程冷启动两次,看第一帧是不是新背景、有没有先闪一下旧图;再从后台恢复一次,确认不会重新走启动页;然后去设置里看版本号 3.2.1;最后把包发给两个用旧手机的朋友,确认 Android 10 和 Android 14 上都能装、都能起。verify 输出的证书指纹和我本地归档的一致,说明还是同一把钥匙,老用户可以直接覆盖升级。
这个案例里有个小插曲。第一次附件说明我只写了“启动图”,提交时被拦下,因为用途不足 10 个字。当时觉得麻烦,后来认真写成“冷启动第一屏背景,铺满不裁切,中间留出 logo 安全区”,AI 给的图一次就对了。约束逼着我把“铺满还是留白、裁不裁、安全区在哪”想清楚,反而省了第二次返工。
交付时一个老用户问,能不能保留旧版启动页,春节后再切回来。我没有留两套工程,而是把 3.2.0 的 source.apk 和这次的最终包一起归档,交付说明里写清楚两个包的 versionCode。节后要回退,重新导入旧包、改版本号、用同一把钥匙签名即可。可回滚不是一句承诺,是 source.apk、签名证书和日志三样东西都在。
启动页改完要在真机上冷启动看第一帧,模拟器截图只能作为参考。
| 对比项 |
案例一 · 授权内部工具 |
案例二 · 自家记账 App |
| 改动内容 |
图标、应用名、版本号、启动页小字 |
启动页背景、开屏广告、版本号 |
| 签名 |
客户提供的 JKS,保持证书一致 |
自有 JKS,默认 v1+v2+v3 |
| 关键附件 |
图标源图、启动页设计稿、授权扫描件 |
两档启动图、安全区说明 |
| 验证重点 |
桌面图标、应用信息、证书指纹 |
冷启动首帧、后台恢复、版本号 |
| 交付物 |
最终包、pack.log、三张截图、授权说明 |
最终包、pack.log、双机安装记录 |
交付不是发一个 APK,而是让客户能装、能看、能回查。
五个人怎么用它接单:用户评价与合规提醒
下面这些评价来自我熟悉的几个接单同行,身份和场景各不相同。他们说的不是“工具多神”,而是流程里哪一段被接住了。
“我最怕客户改到第三版才说‘还是第一版的图标好’。现在项目目录里 source.apk 一直在,历史也能回填,重开一版比解释半天快。授权书我每次都让客户先发,包名对不上不接。”
—— 老陈,独立开发者
“我们三个人做外包,最怕交接。现在每个项目都有 pack.log,签名、对齐、校验走到哪一步一目了然。客户半年后问当时怎么签的,直接翻日志,不用把离职同事的聊天记录找出来。”
—— 阿岚,外包负责人
“双窗口是我留下的原因。左边需求原文,右边 AI 工作区,改的时候不用背客户的原话。从资源管理器拖图进去也不会被挡,改完自动装到测试机,省了我来回按 Alt+Tab。”
—— 小周,小团队主理人
“企业内网工具经常要换 API 地址和版本号,签名的 keystore 又是客户保管。以前最怕签完装不上,现在 verify 会把证书打出来,装之前就知道对不对。口令走环境变量这点,做甲方的会懂。”
—— 林工,企业信息化外包
“我是兼职接单,晚上时间碎。点完修改可以去哄孩子,回来包已经打好了。附件必须写用途这条一开始嫌烦,后来发现写清楚一次,比返工三次省时间。”
—— 阿凯,兼职接单开发者
合规提醒:先有权,再谈改
本文所有方法只适用于你拥有自有版权的应用,或已拿到权利人明确授权的应用。接单前至少确认三件事:授权书覆盖目标包名;授权范围包含本次改动;授权期限覆盖交付与使用周期。客户说不清版权归属的包,不接。
请勿用于破解付费内容、绕过安全机制、去除他人应用的功能限制,也不要改来源不明的商业应用。话术库是表达工具,不是授权凭证;能不能改,取决于你有没有权利,而不是工具能不能做到。
把这条流水线跑顺之后,我做过一次很朴素的复盘:一单小改,原来要在六个程序之间切换十几次,现在固定在两个窗口里完成;原来要手动敲的命令,现在由四步流程接管;原来靠记忆回答的“当时怎么签的”,现在有 pack.log。省下来的不是某一个环节的几分钟,而是每次切换后重新进入状态的那段时间。对一个人接单来说,能连续工作两小时,比零散地快十次更值钱。
回到最开始那个问题:一个人接改包单,瓶颈到底是什么?我的答案是上下文,而不是技术。技术可以查文档,命令可以抄,唯独“这个包改到哪了、上次客户怎么说的、签名用的哪把钥匙、装上去有没有问题”这些状态,一旦散落在六个窗口里,就会不断把人拉回起点。
流水线的意义,是把这些状态收进同一个项目:aapt 先把包说清楚,话术和附件把需求说清楚,ai_done.flag 把“改完了”变成可等待的信号,四步打包和 verify 把“能装”变成可验证的事实,adb 把“客户能看到”提前到交付之前,pack.log 把“当时怎么做的”留下来。人负责判断和沟通,程序负责衔接和复现。
下载卡 · 手机端也能改
智能修改安卓版
不用开电脑,在 Android 10 及以上的 ARM64 手机或平板上导入 APK,本地完成反编译、修改、回编、对齐、签名,成品可以直接安装或分享。第一次使用会按需下载运行环境,之后不用重复下载。
- 支持 APK、JAR、APKS、XAPK、APKM 导入;
- AI 改包、自动回编、v1+v2+v3 签名;
- 项目文件、日志可查,成品可安装可分享。
立即下载
请仅修改自有版权或已获授权的应用;请勿用于破解。电脑版与安卓版都可在 www.apkeditor.cn 了解。