这里是安卓修改大师智改工坊。工坊的固定口号是“只需说话,就能让应用变成你想要的样子”,那是给自然语言路线准备的;换成修改大师经典版这条手动路线,我更愿意把它翻译成另一句话:每一处改动都看得见,改坏了能退回,换台机器还能复现。今天这篇只讲资源——图片、图标、颜色、字符串、布局,一行 smali 都不碰。文末会把回编、对齐、签名、安装验收和导出 Android Studio 工程的顺序串起来,介绍页在这里,需要对照界面时可以先看一眼。
只换资源不碰代码,经典版适合谁
很多人对“改资源”有误解,以为不过是把图片同名覆盖、把文字改一改。真上手才发现问题密集:图标有五六套密度,9-patch 图旁边那圈黑线一碰就废,字符串里藏着占位符,布局的边距写在 dimens 里,颜色还被主题和状态选择器套了两层。资源不是孤立文件,而是一张由名字、限定符和引用关系织成的网。你动的是一张图,编译时校验的却是整张网。
修改大师经典版走的正是这张网。它是 Windows 桌面的手动精修工具,安装包约 13.74 MB,环境要求 ASP.Net 4.5+ 与 JDK 1.8+。它把反编译、资源与 smali 修改、回编打包这些环节摆在你面前:手动反编译,工程目录里的每个文件都能打开;改完能回编;支持导出 Android Studio 工程继续维护;支持多渠道打包和自动脱壳修复;另外带在线封装 APP 以及日志、装机、文件管理等小工具。它不替你做决定,但把每一步的控制权留给你,这正是资源精修最需要的东西。
所谓“只换资源”,范围要划清楚。可以动的是 res/values 下的字符串、颜色、尺寸、样式与主题;res/drawable 与 res/mipmap 下的图片和图标;res/layout 下的界面结构;res/color 下的状态颜色;res/font 下的字体;res/raw 下的原始文件;以及 AndroidManifest 里与应用名、图标、主题相关的属性。不要动的是 smali 里的方法逻辑、lib 下的原生库、以及任何与校验、授权、支付相关的代码。assets 目录要单独判断:如果里面是网页、配置或离线素材,改之前先确认它不承担业务逻辑。
手动路线的好处不玄乎。第一是可审查:改前改后各留一份工程,差异一目了然。第二是可回退:资源替换失败,换回原文件即可,不必从头再猜。第三是可复现:把资源清单写进交付说明,同事照着做能得到同样结果。第四是适合团队交付:设计给图、运营给文案、开发验收,各自只碰自己那一层。缺点也要说清楚:它不改变程序行为,遇到写死在代码里的颜色、拼在代码里的文案,单靠资源改不彻底;遇到加固或分包复杂的包,先解决工程可读性再谈精修。
还有一条底线必须先摆在前面:本文所有操作只针对自有版权、内部应用或已获得明确授权的应用。请勿用于破解、去除付费限制、绕过安全机制,也不要修改他人商业应用后分发。使用的字体、图标、图片同样要有授权,开源素材要保留其许可证要求。技术上做得到,不等于法律上可以做。
资源不是散落的文件,而是一张名字、限定符与引用关系组成的网
资源目录与资源 ID:先把地图摊开
反编译完成后,工程根目录大致是这样:AndroidManifest.xml 描述包名、版本、组件与权限;res 是资源主战场;smali 与 smali_classes2 等目录是反编译出的字节码;lib 放各 ABI 的原生库;assets 放原样打包的文件;META-INF 是签名相关信息;resources.arsc 是编译后的资源表;apktool.yml 记录反编译参数与版本信息。只改资源时,注意力集中在 res、AndroidManifest.xml 和 resources.arsc 的联动上,后两者通常不需要手改,回编时会重新生成。
res 下面按类型分目录,每个目录名就是资源类型:
- values:不针对具体屏幕的键值资源,strings.xml、colors.xml、dimens.xml、themes.xml 等都在这里。
- drawable 与 drawable-xxxhdpi 等:普通图形、形状、选择器,按密度或状态分目录。
- mipmap 与 mipmap-anydpi-v26:启动图标,后者常放自适应图标的 XML。
- layout:界面结构;layout-land、layout-sw600dp 是对应限定符版本。
- color、xml、raw、font、anim、menu:分别放颜色状态列表、配置类 XML、原始文件、字体、动画与菜单。
目录名后面的后缀不是装饰,而是限定符。drawable-xxhdpi 表示给超超高密度屏幕用的图;values-zh-rCN 表示简体中文;values-night 表示深色模式;layout-land 表示横屏。系统按当前设备配置挑选最合适的一份,找不到就回退到无后缀的默认目录。理解这一点,后面替换图片和文案才不会只改一份、其他机型仍旧老样子。
资源在代码和布局里通过名字引用,写作 @drawable/ic_logo、@color/brand_primary、@string/app_name、@dimen/page_margin、@layout/activity_main;主题属性则写作 ?attr/colorPrimary。编译后,每个资源会得到一个形如 0x7f0x0000 的整数 ID,R 类就是这些 ID 的索引。你看到的 XML 是“名字的世界”,系统运行时用的是“ID 的世界”,resources.arsc 负责把两者对上。回编时工具会重新分配 ID,所以不要手改 resources.arsc,也不要为了“固定 ID”去动工程里的公共 ID 映射文件;按名字引用、整包回编,才是稳的做法。
定位资源有三条实用路径。第一条从界面反推:看到某个按钮,先在 layout 里搜它的文字或 id,顺着 android:background 找到 drawable,再顺着 android:textColor 找到 color。第二条从值反查:拿到品牌色的十六进制值,在 res 目录里全局搜索,命中的 colors.xml、color 选择器、layout 内联颜色都会浮出来。第三条从清单入手:AndroidManifest 的 android:icon 指向启动图标,android:roundIcon 指向圆形图标,android:label 指向应用名,theme 指向主题。三条路径交叉验证,基本不会漏。
还有一种情况会让定位变难:资源名被压缩过。有些发布包为了减小体积,会把 res 下的文件名改成 aB.png、cD.xml 这样的短名,布局里的引用也跟着变短。这时不要按“看起来像什么”去猜,而要从引用关系反推:先在 layout 里找到控件,顺着 @drawable/ 或 @mipmap/ 的名字找到实际文件,再确认它对应的业务含义。改名之前更要谨慎,短名往往被多处引用,改一个漏一个就会回编失败。若团队保留了资源映射表,优先查表;没有映射表,就用“布局—资源—页面”的三角关系逐条确认,宁可慢一点,也不要在压缩过的名字上做批量替换。
动手前做两件事:把原始 APK 和反编译工程各备份一份,工程目录名带上日期与用途;再列一张改动清单,写清楚“哪个文件、改成什么、为什么”。这张清单后面会变成验收表和交付说明,也会在你回编失败时告诉你最近动过什么。资源修改最怕的不是难,而是改动散落、无人记得。
换图片与图标:密度、9-patch、命名
图标是资源修改里最容易被低估的一块。桌面上看到的那一枚小图,背后往往不止一个文件:AndroidManifest 的 android:icon 指向 @mipmap/ic_launcher,工程里同时存在 mipmap-mdpi 到 mipmap-xxxhdpi 的多份 PNG,Android 8.0 之后还有 mipmap-anydpi-v26/ic_launcher.xml 描述自适应图标,里面再引用前景层和背景层。只替换其中一张,结果可能是模拟器上变了、真机上没变,或者桌面变了、应用信息页里的图标还是旧的。动手前先把这条引用链走一遍,确认自己到底要改哪几层。
传统启动图标按密度准备,常见尺寸是:
- mdpi:48 × 48 像素,基线密度。
- hdpi:72 × 72 像素,约为基线的 1.5 倍。
- xhdpi:96 × 96 像素,2 倍。
- xxhdpi:144 × 144 像素,3 倍。
- xxxhdpi:192 × 192 像素,4 倍。
这组数字只适用于启动图标。普通界面图片的尺寸由设计稿和布局里给的宽高决定,不能照搬。原则是:每个密度目录里有什么文件,就按同样的文件名和目录结构替换;如果某个密度缺失,系统会拿邻近密度缩放,放大就糊、缩小就损失细节。最稳的做法是让设计按每个目标尺寸单独导出,而不是拿一张 1024 像素的大图批量缩,尤其是有细线条和小字的图标,批量缩容易发虚。
替换时守住三条:文件名不变、扩展名不变、所在目录不变。原图是 ic_launcher.png,新图也叫 ic_launcher.png;原图是 WebP,就别把 PNG 直接改后缀冒充,编码不对会在回编或安装时报错。需要透明背景就用带 Alpha 通道的 PNG 或 WebP,不要用 JPEG,JPEG 没有透明通道,圆角外侧会变成白底或黑底。另外别把阴影、外发光直接烘焙进图标,很多启动器会自己加投影,叠加后显脏;如果原图自带留白,新图也保持相近的视觉重量,否则一排图标里会显得忽大忽小。
9-patch 是图片部分最需要单独讲的一类。它以 .9.png 结尾,最外圈有一像素宽的黑线:上边和左边画黑线,表示哪些区域可以拉伸;下边和右边画黑线,表示内容可以占用的范围,也就是内边距。聊天气泡、对话框背景、带边框的按钮常用它。用普通修图软件裁掉或涂掉这圈黑线,图片会变成普通 PNG,拉伸时边角变形、文字贴边。要改颜色或纹理,应该用支持 9-patch 的编辑工具,改内部像素,保留四周标记;要换尺寸,也先确认拉伸区和内容区仍然合理。若确实想用普通图替代,必须把文件名里的 .9 去掉,并同步修改所有引用,同时接受内边距丢失的后果,通常不建议这么做。
自适应图标则是另一套规则。mipmap-anydpi-v26 下的 XML 用 foreground 和 background 两层描述图标,系统会按厂商的形状遮罩裁切。前景层画布通常是 108 × 108 dp,真正安全的内容集中在中间约 66 dp 的圆形区域内,超出部分可能被裁掉。换图标时,前景图要把主体放在安全区内,背景层可以是纯色,也可以是纹理。Android 13 起还支持单色主题图标,如果原工程提供 monochrome 层,替换时别忘了它,否则开启主题图标后仍是旧图形。改颜色时,背景色通常在 colors.xml 或 XML 里直接写死,改完记得在深色模式下再看一眼。
资源改名要格外克制。Android 资源名只允许小写字母、数字和下划线,不能以数字开头,不能有大写字母、连字符和中文。很多人替换图片时顺手把 ic_old.png 改成 ic_new.png,结果布局里的 @drawable/ic_old 找不到资源,回编直接失败;更隐蔽的是 smali 里也按名字或 ID 引用了它,编译能过,运行时才崩。正确顺序是:优先保持原名;确实要改名,先在 res、AndroidManifest.xml 和 smali 目录里全局搜索旧名,把所有引用一起改,再回编验证。删除资源同理,删之前先确认没有任何引用。
最后是图标缓存。覆盖安装后,部分启动器仍显示旧图标,这不是包没改成功,而是桌面缓存没刷新。验收时先卸载旧版再装新版,或者换一个启动器、进系统设置的应用信息页看图标。应用信息页通常读的是包内资源,比桌面更可信。若应用信息页已经变了、桌面没变,基本可以判定是缓存问题;若两处都没变,再回头检查是不是只改了普通 mipmap,漏了 anydpi-v26 的自适应图标。
还有一类“图片”其实是 XML 矢量图,放在 drawable 下,根节点是 vector,用 pathData 描述轮廓,用 fillColor、strokeColor 描述颜色。它的好处是任意缩放不糊,坏处是不能再当普通 PNG 替换:把 vector XML 删掉换成同名 PNG,引用虽然还能解析,但代码里如果按矢量特性设置 tint 或动画,效果可能变化;反过来把 PNG 换成 vector,也要确认 minSdk 与渲染方式支持。改矢量图时,先看 fillColor 是写死还是引用 @color,能改颜色资源就不要动路径;需要改形状,再用矢量编辑工具调整 pathData,改完在大小两种尺寸下各看一次。
一枚桌面图标可能同时包含多密度 PNG 与自适应图标的两层描述
换颜色:从 color 资源到主题继承
颜色看起来最好改,实际最容易改漏。规范一些的工程会把品牌色集中在 res/values/colors.xml,写成 <color name="brand_primary">#0B6CF0</color> 这样的键值对,布局和主题通过 @color/brand_primary 引用。颜色值支持 #RGB、#ARGB、#RRGGBB、#AARRGGBB 四种写法,最后一种前两位是透明度,00 全透明、FF 不透明。改品牌色时只改这一处,所有引用它的地方会一起变,这是资源化带来的最大便利。
但“引用它”的地方分好几层。第一层是主题:themes.xml 里定义 colorPrimary、colorPrimaryVariant、colorOnPrimary、colorAccent,以及状态栏、导航栏、窗口背景等属性,很多控件的默认配色从这里继承。第二层是布局:有的布局直接用 ?attr/colorPrimary 取主题色,有的则写死 android:textColor="#333333"。第三层是代码:smali 里可能有 Color.parseColor 或直接写死的整数颜色。只改 colors.xml,第一层会跟着变,第二层里写死的不会变,第三层更不会变。判断方法很简单:全局搜索这个十六进制值,看它出现在哪些文件里,再决定改哪里。
主题继承也值得说清楚。应用主题通常继承自某个 Material 或 AppCompat 主题,父主题已经定义了一大套颜色;子主题只覆盖需要改的键。你改 colorPrimary,按钮、开关、输入框光标、选中态可能一起变,因为它们的默认样式引用了主题属性。反过来说,如果某个控件在布局里显式指定了颜色,主题再改也影响不到它。遇到“改了一处、有的页面变有的没变”,先别怀疑工具,回到布局里找显式颜色。
按钮和链接这类会随状态变化的元素,往往用颜色状态列表,放在 res/color 下,XML 里用 selector 按 pressed、focused、enabled、disabled 等状态给不同颜色。只改默认态,按下时可能还是旧色;只改文字色,背景的 ripple 高亮可能还是旧色。换主色时,把同一组状态色一起过一遍:默认、按下、禁用、选中,各自与背景的对比是否足够,禁用态是否还能看出“不可点”。这类细节不做,界面会出现一块新蓝、一块旧蓝的拼接感。
深色模式是另一个高频漏点。工程里如果有 values-night/colors.xml,系统切到深色时会优先用那一份;你只改 values/colors.xml,浅色模式变了,深色模式仍是旧配色。验收时把系统切到深色再走一遍关键页面,重点看文字与背景、分隔线、卡片阴影、状态栏图标。浅色背景配深色状态栏图标、深色背景配浅色图标,这个对应关系如果弄反,状态栏会“消失”。主题里的 windowLightStatusBar 一类属性就是管这个的,改背景色时顺手确认。
具体操作可以按这个顺序:先从设计稿或品牌规范拿到准确色值,写进改动清单;再在 res 目录全局搜索旧色值,把命中分成“资源定义”“主题定义”“布局内联”“选择器状态”四类;资源定义改一处即可,其余三类逐条判断是否跟随;改完不要急着全量替换 smali 和 assets 里的同值字符串,那些可能是业务数据或网页样式,误改会引入无关问题。最后做一次对比截图:改前改后同一页面并排看,色差、对比度、图标可见度一眼就能发现。
主色不只是一个色值,还牵着主题、状态列表与深色模式
改字符串:文案、多语言与占位符
字符串资源住在 res/values/strings.xml,一条一条写成 <string name="key">文本</string>。应用名通常在 app_name 这个键里,AndroidManifest 的 android:label 引用它;界面上的按钮、标题、提示语各有自己的键。规范工程里,所有面向用户的文字都应该在这里,但现实中的工程未必规范:有的直接把文字写在布局的 android:text 属性里,有的拼在 smali 里,有的从服务器下发。改文案前先搜一遍,确认目标文字到底来自哪里,否则会出现“strings.xml 已经改了、界面上还是旧字”的情况。
XML 的转义规则必须遵守。文本里的 & 要写成 &,小于号写成 <,大于号写成 >;单引号在 Android 字符串里通常要写成 \',双引号写成 ";如果字符串以 @ 或 ? 开头,要写成 \@ 或 \?,否则会被当成资源引用或主题属性。换行用 ,制表符用 \t。想给部分文字加粗,可以在字符串里写 <b>…</b>,再用 getText 而不是 getString 去取;但只有代码配合时才生效,改文案时不要贸然加标签。最稳妥的做法是:只改文字内容,不动标签结构,改完让 XML 解析器过一遍。
布局里还有一种“假文字”叫 tools:text,只在预览时显示,运行时不生效。搜文案时如果只盯着它改,装到手机上会发现界面还是空的或还是旧字;真正生效的是 android:text,或者代码里动态设置的内容。反过来,android:text 写死的文字虽然能直接改,但不利于多语言,规范做法是抽到 strings.xml 再用 @string 引用。抽离时保持键名有意义、避免和已有键冲突,改完把布局里的硬编码删干净,别留下“资源改了、布局还写死一份”的双份来源。
带占位符的字符串是事故高发区。像“共 %1$d 条记录”“欢迎回来,%1$s”这样的文本,百分号部分由代码在运行时填入。你可以改前面的中文,可以调整语序,但占位符的数量、类型和编号必须保留;把 %1$s 删掉,代码仍会传参,轻则显示异常,重则抛异常;把 %1$d 改成 %1$s,类型不匹配也会出问题。带多个参数时,编号决定顺序,调整语序要同步调整编号,不能只改文字顺序。遇到 formatted="false" 的字符串,说明它不按格式化规则解析,里面的百分号可能只是普通字符,改之前先看清属性。
复数和数组是另外两种形态。复数字符串放在 plurals 里,按 quantity 给 one、other 等不同形式,英文有单复数,中文通常只用 other,但结构不能少;数组放在 string-array 里,适合下拉选项、帮助条目。改这类资源时,条目数量要和代码预期一致,代码按索引取第 3 项,你删成 2 项就会越界。应用名、渠道名、SDK 密钥这类不该翻译的字符串,常带 translatable="false",看到这个属性就不要动,尤其不要为了“统一品牌”去改第三方 SDK 的标识。
多语言工程要按语言目录逐份处理。默认的 values/strings.xml 是兜底,values-en 是英文,values-zh-rCN 是简体中文,values-zh-rTW 是繁体,values-ja 是日文。系统按当前语言选最合适的一份,缺失的键回退到默认。只改默认值,英文和繁体用户仍看到旧文案;只改中文,默认兜底可能还是旧的。正确做法是先确定这次要覆盖哪些语言,再逐份替换同名键。如果某个语言文件里缺少这个键,回退逻辑会让它显示默认语言,这时要么补齐,要么接受回退,别留一半新一半旧。
改应用名是最常见的需求,也最能暴露工程结构。标准做法是改 app_name 的值,清单里的 android:label 保持 @string/app_name 不变;如果清单里写的是硬编码文字,直接改清单,但这样就没有多语言能力;如果代码里还有一处 setTitle 或启动页文字写死旧名,资源改完仍会在某些界面露馅。验收应用名要看四个地方:桌面图标下方、最近任务卡片、系统设置的应用信息页、应用内的关于页。前三个通常读清单和资源,第四个可能来自代码或服务器,四处一致才算改干净。
文案长度会直接影响布局。中文通常比英文短,把英文换成中文,按钮可能空出一截;把中文换成英文或俄文,按钮可能换行、被截断,甚至把旁边的图标挤走。改完不要只看自己手机:把系统字号调大一级,看看按钮是否还完整;把屏幕切到横屏,看看标题是否只剩一半;如果有小屏设备或平板,也各看一眼。确实放不下时,优先改文案长度或布局的换行策略,不要靠缩小字号硬塞,字号小于系统下限,阅读体验会明显变差。
还有两类文字不在资源里:一类在 assets 的网页、JSON、离线帮助文档中,改它们等于改前端内容,要和改资源分开评估;另一类由服务器下发,本地怎么改都不会变。遇到后者,不要在客户端里硬编码覆盖,也不要伪造接口返回,这已经超出“换资源”的范围。把能改的改到位,把不能改的写进交付说明,比留下一个“看起来改了、实际没改”的假象更专业。
调布局:边距、圆角、尺寸的分寸
布局文件在 res/layout 下,一个界面一个 XML,根节点通常是 LinearLayout、RelativeLayout、FrameLayout、ConstraintLayout 或 CoordinatorLayout。改布局不是“把数字调大调小”这么简单:margin 是元素外侧的间距,padding 是元素内侧的留白;dp 随屏幕密度换算,sp 还会跟随系统字号;match_parent 占满父容器,wrap_content 包住内容。弄混这四个概念,改出来的界面往往在另一台设备上完全变形。
尺寸最好走资源。规范工程把常用间距写在 res/values/dimens.xml,布局里用 @dimen/page_margin 引用;有的还为不同宽度准备 values-sw360dp、values-sw600dp,为横屏准备 layout-land。改一处 dimens,所有引用它的页面一起变,这比逐个布局改数字可靠得多。如果布局里写的是 16dp 这样的字面值,也可以直接改,但要先全局搜索同值,判断它是“这个控件独有”还是“全站统一间距”。前者可以就地改,后者应该抽到 dimens 再统一调整,否则下次改版又要翻一遍。
圆角通常不是一个属性,而是一张背景图。传统做法是在 res/drawable 下建一个 shape XML:shape="rectangle",solid 填底色,corners 的 radius 填圆角半径,stroke 描边,padding 控制内容与边缘的距离,然后在布局里用 android:background="@drawable/bg_rounded" 引用。想改圆角,只改 radius;想改底色,只改 solid;想加描边,补 stroke。CardView 用 cardCornerRadius,MaterialButton 用 cornerRadius,不同控件走不同属性,改之前先确认它用的是哪一种,别把 shape 的 radius 和控件的 cornerRadius 混为一谈。
圆角与内容要配套。背景有了 12dp 圆角,里面的文字和图标如果贴着边,视觉上仍像被切了一块;通常要给同样的背景加 padding,或者给父容器留出内边距。带按压反馈的按钮,背景可能是 ripple 包着 shape,改 shape 的圆角后,ripple 的裁切范围也要跟着一致,否则按下去的高亮会露出直角。API 版本较新的工程还会用 clipToOutline 让子 View 跟随轮廓裁切,这时图片圆角由轮廓决定,不再是单独一张图。看清实现方式再动手,比盲目替换背景图有效。
边距调整要顾及约束关系。ConstraintLayout 里,两个控件之间的间距可能由 margin 决定,也可能由约束链、Guideline 或 Barrier 决定;只改 margin,链条另一端的控件可能被挤到屏幕外。LinearLayout 里,weight 决定剩余空间怎么分,给某个子项加 margin,其他子项的可用宽度会变小。RelativeLayout 里,下边距可能同时影响“在谁下方”的定位。改完一个值,至少检查同排、同列、上下相邻的三个元素,确认没有重叠、截断或异常留白。
触控尺寸与字号要守住下限。按钮、开关、列表项这类可点击元素,视觉高度可以精致,但可点击区域不宜太小,手指点不准的界面再好看也不好用。文字用 sp,不要用 dp 固定字号,否则用户调大系统字号时界面不会跟随。固定高度的按钮在字体放大后容易出现文字被裁,改用 wrap_content 加 minHeight 更稳。图标与文字并排时,给文字留出可换行的余地,或者设置 maxLines 与 ellipsize,让它在极窄屏上至少显示得体面。
多套布局要一起看。layout-land 是横屏,layout-sw600dp 是平板,layout-night 可能还有深色专用图。只改默认布局,横屏和平板可能仍是旧样式;反过来,如果横屏布局里复用了同一个 include,改一处会同时影响两处,改之前先确认 include 的层级。列表项、对话框、底部弹层也各有自己的布局文件,主页面改完,别漏了这些“二级界面”。
布局里的重复样式也值得收拢。多个按钮共用同一套圆角、底色、内边距时,与其在每个布局里复制一遍,不如在 values 下定义 style,让按钮通过 style 属性引用;改的时候只动 style,所有引用处一起变。收拢之前先确认这些控件真的应该一致,别把“取消”和“确认”的视觉差异一并抹平。样式继承也要看清,子样式只覆盖差异项,父样式改了,子样式会跟着变;如果某个页面突然和别处不一样,先查它是不是引用了另一套 style,而不是急着改布局数字。
布局的验证比改更花时间。准备四个观察点:小屏手机、大屏手机或平板、横屏、系统大字号。每个观察点走一遍改动页面,看文字是否完整、按钮是否可点、图片是否变形、圆角是否一致、背景是否透出。能并排截图就并排截图,肉眼对比比记忆可靠。若工程复杂、布局预览不方便,可以先把工程导出到 Android Studio,用布局预览和 Design 视图检查约束,再回到经典版完成资源替换,这条组合路线后面会细说。
边距、内边距、圆角与触控尺寸,需要一起看而不是单点调
实例一:给自家记账应用换图标与主色
先说背景。这是我们自己团队维护的记账应用,包名、签名、源码都在手里,改完只在内部和授权渠道分发。需求很具体:换上新版 logo,把主色从旧蓝换成品牌绿,桌面图标、应用内主色、状态栏要一起变,不能出现“图标绿了、按钮还是蓝的”。这类需求最适合走资源路线,不需要动任何业务逻辑。
以前的做法是:设计给一张 1024 像素的 logo,我用修图软件手动导出 48、72、96、144、192 五套 PNG,逐个改名覆盖;主色则在 colors.xml 里改一处,再去两个布局里找写死的色值,凭记忆补状态栏颜色;然后走命令行回编、对齐、签名,装到手机上看看。问题有三个:自适应图标经常漏掉,Android 新系统上桌面仍是旧图;状态栏颜色漏改,顶部还是旧蓝;每次打包要重复记命令,换台电脑就得重新配环境。一轮下来耗时不少,还不敢保证没漏。
现在的做法是:在修改大师经典版里导入自家 APK,手动反编译后先看资源地图。AndroidManifest 的 icon 指向 ic_launcher,mipmap 下有五套密度,anydpi-v26 下还有自适应图标 XML。按前面的规则,五套 PNG 用设计给的分尺寸图逐一替换,文件名和扩展名保持原样;自适应图标的前景层换成新 logo,背景层改成品牌绿的浅色底;roundIcon 如果存在也一并替换。颜色侧先改 colors.xml 里的 brand_primary,再检查 themes.xml 的 colorPrimary、colorPrimaryVariant、colorAccent 是否引用它,状态栏和导航栏颜色是否单独写死;最后全局搜索旧蓝色值,把布局里残留的内联色一并换掉。改完在工具里回编、对齐、签名,产物直接安装。
验证分四步。第一步卸载旧版再装新版,排除启动器缓存干扰,看桌面图标、圆形图标、应用信息页图标是否都是新 logo,缩小到列表尺寸后是否还认得清。第二步打开应用,看顶部栏、主按钮、选中态、开关、进度条是否统一成品牌绿,按下和禁用状态有没有漏网的旧蓝。第三步把系统切到深色模式,确认背景、文字、状态栏图标仍然协调。第四步看日志和签名:启动无资源找不到的报错,签名校验通过,版本号按计划递增。四步都过,才算这次换肤完成。
这次改动还有一个收获:把资源清单固定下来了。哪几个 mipmap 目录、哪几个颜色键、哪几个布局文件,写成一张表放在项目说明里。下次再换品牌色,不用重新摸索,照着表走一遍,很快就能完成并验收。手动路线的价值就在这里——第一次慢,后面越来越稳,而且每一步都能解释给别人听。
实例二:改按钮文案、边距与圆角
第二个实例还是自家应用,一个内部教学工具,课程列表底部有一排操作按钮。运营提了两个需求:把“报名”改成“立即开始学习”,把按钮左右边距收紧一点,圆角从 6dp 调到 10dp,整体看起来更轻。听起来是三处小改动,实际牵涉字符串、尺寸、背景形状和布局约束四类资源,正好用来演示“改一处、看三处”的方法。
以前的做法是:直接在 layout 里找到 android:text="报名",改成新文案;按钮宽度写死 96dp,文字变长后先被截断,只能把宽度改大;左右 margin 各 16dp,改成 12dp 后右边图标被挤出去,又把图标宽度改小;圆角背景是一张 PNG,找设计重新导出一张,覆盖时忘了改按下态,按下去还是旧圆角。来回装了三遍才勉强能看,而且改过的数字散落在两个布局文件里,下次维护还得重新找。
现在的做法是:先在修改大师经典版里反编译工程,定位按钮所在的 layout。文案不在布局里,而是引用 @string/course_action,于是回到 strings.xml 改值,保留原来的键名;同一条文案如果还出现在详情页或弹窗,全局搜索这个键,确认都跟着变。按钮宽度从固定 96dp 改为 wrap_content,补上 minWidth 和左右 padding,让文字自己撑开;左右边距如果引用 @dimen/card_gap,就改 dimens.xml 一处,如果是字面值,则改成引用同一个 dimens,避免下次再散落。圆角背景在 res/drawable 下是 shape XML,把 corners 的 radius 从 6dp 改成 10dp,solid 颜色不变;按下态如果单独有一份 selector,同步改它的圆角引用。改完回编、对齐、签名,安装到测试机。
验证要看四组场景。第一组是文字长度:新文案比旧文案长,在最小宽度手机上是否换行、是否被截断、按钮是否把旁边的图标挤走;把系统字号调大一级再重复一次。第二组是间距:按钮与卡片边缘、按钮与按钮之间是否均匀,右边距收紧后有没有贴边,圆角变大后内容是否需要补 padding。第三组是状态:默认、按下、禁用三种状态下,圆角和颜色是否一致,按下高亮有没有露出直角。第四组是回归:按钮点击后的跳转、埋点、权限判断是否仍然正常,资源改动不应影响这些行为,但验收时仍要确认。四组都过,再把改动前后的截图并排存档。
这个实例说明了一件事:文案、尺寸、圆角看似三个独立改动,其实共享同一套引用关系。字符串决定内容长度,长度影响宽度与换行,宽度又受边距和父容器约束,圆角则决定内边距的视觉需求。按“字符串—尺寸—布局—背景”的顺序改,比在布局里见一个改一个更有章法。改完把键名、旧值、新值、影响页面记进清单,下次运营再提类似需求,直接查表即可。
文案变长会牵动宽度、换行、边距与圆角,验收要成组看
回编、对齐、签名:把改动变成可安装的包
资源改完只是半成品,真正容易翻车的是回编。回编前先做一轮自检,能省掉大半报错。XML 是否闭合、属性引号是否成对、特殊字符是否转义;资源文件名是否只含小写字母、数字和下划线,有没有以数字开头;图片扩展名与实际编码是否一致,9-patch 的外圈黑线是否完整;字符串里的占位符数量是否和原来一致;多语言目录是否只改了该改的那几份。把这些检查变成固定动作,比出错后再回头猜要快得多。
回编时常见的错误其实有规律。“resource not found”多半是引用名和文件名对不上,或者改名后漏改引用;“invalid file name”是命名不合规;“duplicate resources”是同一个限定符目录里出现了同名文件;“9-patch”相关报错要回到图片边框找原因;XML 解析错误会直接指出行号,按行看标签是否闭合。遇到报错不要急着重装工具,先看日志里的第一个错误,后面的错误往往是它的连锁反应。把原始工程和当前工程对比,也能快速定位是哪次改动引入的问题。
回编成功后先对齐,再签名。对齐让包内未压缩数据按固定边界排列,减少安装后的读取开销;签名则决定这个包能不能被设备接受、后续能不能升级。签名要用自己的密钥库,密钥文件、别名、口令妥善保管,口令通过安全的方式传入,不要写进脚本明文,也不要出现在日志里。签名方案通常同时启用 v1、v2、v3,覆盖不同系统版本;签名完成后做一次校验,确认证书主题和指纹是自己预期的那一份。
需要多渠道分发时,打包环节还要多一层确认。不同渠道包使用同一套代码和资源,只在渠道参数上区分;每个包都要完成对齐、签名、校验,不能只验一个就批量放行。渠道参数通常写在清单或配置文件里,改的时候保持格式与键名一致,别把测试环境的参数带进正式包。产物命名带上版本号、渠道、日期,和改动清单一一对应;发布前抽一个包实际安装,确认渠道信息、版本号、签名三项都正确。批量操作最怕“以为都一样”,抽检和记录是把风险压下去的最简单办法。
很多人只看到“打包成功”就结束,实际上签名没贴上,安装时才报错,校验这一步不能省。
安装验收要模拟真实用户路径。覆盖安装适合小改动,但前提是签名一致、版本号递增;签名不一致时系统会拒绝安装,只能卸载旧版,卸载会清掉应用数据,操作前先确认数据可丢或已备份。安装后不要只看桌面,依次检查:启动是否闪退,首屏资源是否正常加载,改动页面是否符合预期,未改动的核心功能是否仍可用,深色模式和横屏是否正常,通知、分享、文件选择等系统交互是否受影响。用日志观察启动阶段有没有资源相关的异常,比肉眼扫一遍更可靠。
可以把验收清单固定成下面几项,每次照着打勾:
- 安装与启动:覆盖安装或全新安装成功,冷启动无闪退。
- 品牌资源:图标、应用名、启动页、关于页四处一致。
- 颜色体系:主色、状态色、深色模式、状态栏图标对比正常。
- 文案体系:默认语言与目标语言完整,占位符显示正确,无截断。
- 布局体系:小屏、大屏、横屏、大字号四组场景无重叠与溢出。
- 核心功能:登录、列表、详情、提交等原有流程不受影响。
- 包体信息:版本号、签名证书、渠道信息符合发布计划。
- 可回退:原始 APK、反编译工程、改动清单、验收截图均已归档。
最后留一条退路。每次发布前保留上一版可安装包和对应工程,出现问题时能回到已知可用的状态;改动清单里记录每个文件的变更原因,出了问题能快速定位;验收截图按日期归档,方便对比。资源修改的风险通常不在“改错一个色值”,而在“改了很多处、没人说得清改了哪些”。把过程留痕,手动路线才能真正做到可控。
导出 Android Studio 工程:从精修走向长期维护
资源改到一定程度,往往会遇到两个需求:一是布局复杂,想在可视化环境里检查约束;二是团队要接手,不能只留一个反编译目录。这时可以用修改大师经典版的导出 Android Studio 工程功能,把当前工程整理成可导入的项目结构。导出的意义不是“绕过打包”,而是把这次精修的结果变成可继续开发、可代码评审、可版本管理的工程。
导出后先在 Android Studio 里做三件事。第一,等待 Gradle 同步完成,确认 SDK、构建工具和 JDK 版本匹配;第二,编译一次,看看资源引用是否全部解析,布局有没有报错;第三,用布局预览逐个打开改动页面,检查边距、圆角、文字换行在可视化视图里的表现。反编译工程里的资源名和引用关系通常能直接编译,但个别第三方库、so 文件或构建脚本可能需要补齐,遇到问题按报错逐项处理,不要一口气全改。
签名配置要换成自己的。导出工程里如果带着旧的签名配置,记得替换成团队密钥库,并把口令放在本地配置或环境变量里,不要提交到代码仓库。构建变体、渠道配置、版本号按发布计划设置;如果工程里有多个模块,确认资源合并顺序,避免同名资源互相覆盖。第一次构建成功后,用和经典版相同的验收清单跑一遍,确保“导出的工程”和“手工回编的包”行为一致。
导出工程里的资源合并规则也要留意。主模块、依赖库、不同构建变体可能提供同名资源,Gradle 会按优先级合并,低优先级的同名文件被覆盖;如果你在经典版里改的是最终包里的资源,导入 Studio 后却发现预览还是旧图,先查是不是被某个依赖或变体覆盖了。排查方法是从报错或预览反查资源来源,确认最终生效的是哪一份,再决定改主模块还是改依赖配置。资源合并的顺序不要凭感觉,构建日志和资源查看器都能给出答案;确认之后再改,避免“改了半天,生效的是另一份”。
团队交付建议附一份说明:资源地图写清楚图标、颜色、字符串、布局分别在哪些目录,关键键名是什么;改动清单列出旧值、新值、影响页面;验收记录附上截图和设备信息;构建说明写清楚 JDK、SDK、签名和渠道参数。设计、运营、开发拿到这份说明,不需要再问“这个绿色是哪个文件”,也不需要重新反编译找线索。手动精修的价值,最终要落到这种可交接的确定性上。
导出的不只是工程,还有一套可评审、可交接的资源改动记录
用户评价
“以前换图标最怕漏密度,现在按目录一层层替换,改完在应用信息页一眼就能确认,桌面缓存的问题也知道怎么排除了。”
—— 老周,独立开发者
“公司内部应用要统一品牌色,我先改颜色资源,再全局搜旧色值,状态栏和按钮的旧蓝终于清干净了,验收时也有清单可对照。”
—— 林工,企业信息化
“按钮文案从两个字改成六个字,原来会被截断。把固定宽度换成自适应,再补上内边距,小屏和大字号下都正常了。”
—— 阿岚,视觉设计
“多语言最容易只改一半,我现在按语言目录逐份核对,占位符不动,改完切系统语言逐页看,返工少了很多。”
—— 陈默,教学产品运营
“最有用的是最后导出工程,布局可以在 Studio 里预览,交付时附上资源清单,同事接手不用再问我文件在哪。”
—— 小北,安卓初学者
合规提醒与下载
资源精修的前提是权利清晰:只处理自有版权的应用,或已取得明确授权的项目;替换的图片、字体、图标同样要有合法来源。请勿用于破解、去除付费限制、绕过安全机制,也不要修改他人应用后分发。开源素材请保留许可证与署名要求,第三方 SDK 的标识和声明不要随意删改。技术上能改,不代表可以越过法律与契约的边界。
只换资源不碰代码,是一种克制,也是一种专业:知道自己改了什么、为什么改、怎么验、怎么退。安卓修改大师智改工坊始终相信,工具只是把手上的事做得更稳;那句“只需说话,就能让应用变成你想要的样子”,在手动路线上同样成立——只不过这里的“说话”,是你对每一个资源键、每一处边距的明确交代。更多版本与工具说明,可访问官网 www.apkeditor.cn 查看。
安卓修改大师智改工坊 · 智能修改安卓版
在手机与平板上完成导入、修改、回编、对齐、签名与安装,适合随时查看成品效果;需要手动精修与导出工程时,再回到修改大师经典版。
立即下载
下载与版本说明:https://www.apkeditor.cn/ai-version.aspx