首页 / 资讯中心 / 文章详情

Unity手游动态更换App图标双端完整方案与防坑指南

Unity手游动态更换App图标双端完整方案与防坑指南 ★ FEATURED ARTICLE
做Unity手游的朋友应该都被运营提过这种需求春节要换节日图标、周年庆要换版本图标、新玩法上线要换LOGO而且经常是“Android和iOS都要支持”。App图标这东西看起来就是桌面上的一个小方块却是App曝光量最高的入口玩家每天看它好几遍运营把它当成免费的活动banner来用一点不奇怪。但这活儿真做起来坑比想象中多。我最早接这个需求时以为就是个“换张图”的事结果发现Android换完图标桌面不刷新、iOS切图标要弹窗让用户确认、切完以后进程莫名其妙被杀还有一部分国产ROM压根不买账。折腾了几个版本才把双端的稳定方案稳定下来这篇文章把完整的技术方案和经验一次性说清楚主要讲清楚为什么这么做、代码怎么写、上线前要检查什么以及真机上会遇到哪些坑。适合Unity客户端开发、想要接换图标需求的技术负责人参考。1. 先定需求动态换图标到底要解决什么问题1.1 两种常见场景技术侧重完全不同先把需求拆清楚因为“动态更换App图标”这句话在不同产品眼里含义不一样后续技术选型也完全不一样。第一种是用户主动切换。比如App里放一个“切换图标”的入口用户喜欢哪个样式自己点选。这种场景对时效性的要求是“切换后最好马上生效”用户点完按钮如果半天没反应体验会很差。而且这类切换通常会做持久化用户这次选了节日图标下次打开App还是节日图标。第二种是运营主动切换。发布时间到了后台配置一个开关App下次启动时自动换上对应的图标。这种场景不需要用户参与但要求“在指定时间点前后表现一致”而且因为用户不感知切换失败往往很难察觉所以这类型需求比用户主动切换更考验成功率。我们做的中国手游市场绝大多数需求是第二种节日活动、版本庆典、买量活动换素材运营会提前把图标做成一整套然后要求客户端在特定时间自动切换。还有少数产品做第一种给玩家一个“换肤”的小玩法顺便在社交媒体上制造话题。这两类需求有一个共同点图标资源本身都得提前打进包里。这一点后文会专门展开讲。1.2 Android 三条技术路线为什么最终锁死 Activity AliasAndroid端的“更换桌面图标”网上能搜到三条路线我刚接触时也犹豫过挨个实验完得出了结论。第一条是 Activity Alias。原理是在AndroidManifest里给同一个真实Activity配置多个“别名入口”每个别名配不同的图标然后在运行时通过PackageManager切换这些入口的启用状态。桌面感知到入口变化后会刷新图标。这是目前Android生态里最接近“换App主图标”的方案也是主流玩家都在用的。第二条是 Dynamic Shortcut / Pinned Shortcut。这个方案本质上是换“快捷方式图标”不是换App主图标。用户长按桌面图标弹出的快捷菜单里可以放几个可变的动态图标项用户可以把某个快捷方式钉到桌面看起来像是换了图标。但问题很明显需要用户手动固定而且钉到桌面的快捷方式样式和主App图标是有区别的它就是个快捷入口不是App本身。对运营想要的那种“全员自动换图标”的需求完全不满足。第三条是自己写一个桌面Launcher替换系统的桌面然后Launcher里想怎么画图标就怎么画。这条路技术上是通的但要让玩家全都换成你的桌面教育成本太高了基本等于自杀。只能在测试机上玩不能产品化。三条路对比下来真正能双端通用、运营可控、玩家无感的只有Activity Alias。不过它也有自己的问题比如部分ROM桌面刷新不及时、切换时可能杀进程这些我们后面会专门讲怎么规避。选型阶段先明确一个原则Android的“动态图标”本质上是“在多个预置入口之间切换”不是把一个图片动态画在桌面上。1.3 iOS 的底线与可行组合拳iOS这边比Android更严格。iOS不支持在运行时任意更换主图标苹果只给了一把钥匙setAlternateIconName。这是iOS 10.3开始公开的系统APIApp可以在Info.plist里预先声明最多一批备用图标然后调用接口在默认图标和备用图标之间切换。但是苹果设置了几条底线第一图标必须打包在安装包里不能运行时从服务器拉第二每次切换系统都会弹一个确认框用户点“好”才会生效第三切换操作本身是异步的有失败回调比如图标名写错、没有声明备用图标等都会报错。另外iOS从14开始有个趋势是系统会自动为App生成“主题图标”比如iOS 18的深色、着色模式那个是系统行为App自己控制不了。iOS端我给的建议是用setAlternateIconName做“主路径”同时配合UIApplicationShortcutItem做“兜底路径”。也就是说当用户长按App图标时快捷菜单里也可以放一个“切换图标”的入口至少多一种唤起方式。这样即使主路径因为系统限制失败玩家也不会完全摸不到切换入口。1.4 所有方案都绕不开的三个硬限制做这个功能前一定要让运营和市场先知道这三个边界不然后面扯皮。第一个硬限制是图标必须预置在安装包内无法热更下载新图标。Android这边Activity Alias的icon属性指向的是APK里的资源iOS的CFBundleAlternateIcons指向的也是bundle里的文件。你在服务器上下载一张图然后直接替换桌面图标在双端原生层面都做不到。所以运营要提前把图标素材全量给到客户端客户端打包时带进包里。我们一般预留8到10个图标位包含春节、周年庆、夏日活动、版本大图等。第二个硬限制是切换不是“点一下马上变”。Android桌面刷新依赖系统广播部分桌面有缓存可能几秒才变iOS弹窗确认后也有延迟。所以如果你做的是运营定时切换不要在“准点瞬间”要求玩家看到新图标设计上要有容忍窗口。第三个硬限制是平台审核和ROM差异。App Store审核时如果发现备用图标涉及时效性很强的营销内容可能需要说明用途Android的各大国产ROM桌面华为、小米、OPPO、vivo对图标变更的处理方式互不一样有的需要重启桌面甚至重启手机才能看到。这些都要在方案设计里提前考虑。2. 双端原生实现与核心原理拆解2.1 Android Activity Alias 的清单配置与切换代码以Unity手游为例真实的主Activity一般叫com.unity3d.player.UnityPlayerActivity或者你在Unity里自定义的继承类。假设你的主入口是com.yourgame.unity.MainActivity现在要加两个图标位一个“默认图标”一个“春节图标”。清单里的写法大概是这样的activity android:namecom.yourgame.unity.MainActivity android:exportedtrue android:configChangesorientation|screenSize|keyboardHidden intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity activity-alias android:name.IconAliasNormal android:enabledtrue android:exportedtrue android:iconmipmap/ic_icon_normal android:labelstring/app_name android:targetActivitycom.yourgame.unity.MainActivity intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity-alias activity-alias android:name.IconAliasFestival android:enabledfalse android:exportedtrue android:iconmipmap/ic_icon_festival android:labelstring/app_name android:targetActivitycom.yourgame.unity.MainActivity intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity-alias注意几个关键点。android:targetActivity必须指向同一个真实存在的Activityalias本身不承载逻辑它只是入口的“马甲”。android:icon指向的必须是打包进APK的资源不能是网络图片。还有一点如果不想让桌面同时显示多个图标同一时刻只能有一个带LAUNCHER的入口是enabled状态所以要做互斥控制。切换代码也用不着什么高大上的东西就是操作PackageManager的组件启用状态ComponentName defaultIcon new ComponentName(context, com.yourgame.unity.IconAliasNormal); ComponentName festivalIcon new ComponentName(context, com.yourgame.unity.IconAliasFestival); PackageManager pm context.getPackageManager(); pm.setComponentEnabledSetting(defaultIcon, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); pm.setComponentEnabledSetting(festivalIcon, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);这里有几个容易踩坑的地方。第一个是传DONT_KILL_APP并不一定能阻止进程被杀如果禁用的是当前正在运行的入口Activity对应的alias系统为了安全可能还是会回收任务栈游戏会冷启动一次。所以调用时机非常重要后面章节展开讲。第二个是不要把所有LAUNCHER入口都禁用了否则App直接从桌面消失看起来就像卸载了这个错误上线后会变成灾难。第三个是切换完以后部分桌面不会立刻刷新可以主动发一个ACTION_PACKAGE_CHANGED广播提示桌面更新Intent broadcast new Intent(Intent.ACTION_PACKAGE_CHANGED); broadcast.setData(Uri.parse(package: context.getPackageName())); broadcast.putExtra(package, context.getPackageName()); try { context.sendBroadcast(broadcast); } catch (Exception e) { // 部分Android 8.0系统限制隐式广播这里吞掉异常即可 }这个广播不是所有桌面都响应但实测部分桌面比如原生Pixel桌面、三星桌面会因此加速刷新发了没坏处不发可能干等着。2.2 iOS 备用图标声明与 setAlternateIconNameiOS端做起来比Android端“干净”因为API就一个没有那么多花活。但也正因为API唯一配置一步都不能错。首先要在Xcode工程或者Unity构建生成的Info.plist里声明备用图标。如果你在原生工程里手动改需要在CFBundleIcons节点下加CFBundleAlternateIcons字典keyCFBundleIcons/key dict keyCFBundleAlternateIcons/key dict keyFestivalIcon/key dict keyCFBundleIconFiles/key array stringFestivalIcon/string /array keyUIPrerenderedIcon/key false/ /dict /dict /dict这里的FestivalIcon是备用图标的逻辑名将来调用setAlternateIconName时传的就是这个名字。CFBundleIconFiles数组里填的是图片文件的名称不带扩展名图片放在Assets.xcassets里或者直接作为bundle资源文件但必须保证尺寸覆盖iOS要求的图标规格通常是20pt到1024pt的一套。然后调用切换import UIKit if UIApplication.shared.supportsAlternateIcons { UIApplication.shared.setAlternateIconName(FestivalIcon) { error in if let error error { // 切换失败打印错误信息定位是不是plist配置有问题 print(切换图标失败: \(error.localizedDescription)) } else { // 切换成功 } } }恢复默认图标把参数传nil即可。这里有几个官方文档里没有明说、但实测很重要的点。第一每次切换都会弹窗。哪怕你只是从春节图标切回默认图标系统仍然会弹“是否更换图标”的确认框用户选择“好”才生效。这意味着你没法在用户完全无感知的情况下偷偷换图标所以如果运营想“零点自动换图标”只能做成启动时调用然后用户下次回到桌面时会看到确认框或者提前做好用户教育。第二setAlternateIconName必须在主线程调用。在Unity桥接时如果直接从C#底层线程回调过来会遇到“UIKit必须在主线程使用”的崩溃必须包一层dispatch到主队列。第三如果你传的图标名在Info.plist里没有声明系统会报NSError。错误信息会提示类似“The specified icon name is not valid”之类的文案。所以上线前要把每个图标名和plist配置对一遍少一个都不行。2.3 双端行为差异对照表做这个功能最烦的就是双端行为不一致提前摆出来心里有底。项目AndroidActivity AliasiOSsetAlternateIconName是否需要用户确认不需要每次切换都要用户确认弹窗图标来源APK内预置资源IPA内预置资源切换生效时间依赖桌面刷新可能数秒到数分钟用户确认后较快生效切换主要风险部分ROM桌面不刷新、进程被杀图标名未声明、主线程问题能否无感切换可以做到无感但ROM差异大不能无感系统强制弹窗是否需要额外权限不需要不需要适合运营自动切换比较适合不适合“偷偷换”需要教育用户恢复默认图标切回对应alias即可传nil即可但同样弹窗这个表格基本说明了双端的性格差异Android给你“能做但地面不统一”的自由iOS给你“统一但严格受限”的规则。方案设计必须两头都要适配。3. Unity 桥接层设计C# 与原生代码的对接实践3.1 原生代码在 Unity 工程里的组织方式Unity手游要调用原生能力工程组织方式有几种我这里说一个在Unity 2018到Unity 6时代都通用、维护成本也低的方案。Android端把Java/Kotlin源文件编译成AAR包放到Assets/Plugins/Android目录下Unity构建时会自动打进APK。如果你不想每次都手动编译AAR也可以直接把.java文件放到Assets/Plugins/Android下的源码目录Gradle构建时会一起编译。但我在实际项目里更推荐AAR方式因为可以顺便把依赖打进包也方便本地调试。iOS端把Objective-C或C的桥接文件放到Assets/Plugins/iOS目录下Unity构建Xcode工程时会把这些文件自动拷贝进去参与编译。注意如果是Objective-C文件需要确保文件后缀是.mm这样编译时走的是Objective-C才能直接在文件里写extern C导出C接口。另外iOS的Info.plist需要在构建后追加内容。这里分两种情况如果你有iOS原生工程经验可以每次手动在Xcode里改但如果要自动化建议写一个IPostprocessBuildWithReport的Editor脚本在构建后自动往生成的Info.plist里写入CFBundleAlternateIcons配置同时把图标图片资源拷贝到Xcode工程里。这样团队里任何人出包都能一致地带上配置不会忘。3.2 C# 层的双端接口封装Unity C#层要提供给游戏逻辑用的接口一般设计成一个静态类内部判断平台。我在项目里通常是这么写的public static class AppIconSwitcher { #if UNITY_IOS !UNITY_EDITOR [DllImport(__Internal)] private static extern void unity_switch_app_icon(string iconName); #endif public static void Switch(string iconName) { #if UNITY_ANDROID !UNITY_EDITOR using (var bridge new AndroidJavaClass(com.yourgame.bridge.IconBridge)) { bridge.CallStatic(switchIcon, iconName); } #elif UNITY_IOS !UNITY_EDITOR unity_switch_app_icon(iconName); #else Debug.LogWarning(当前编辑器环境不支持切换App图标); #endif } }Android侧IconBridge这个类需要拿到Activity的Context。Unity里最靠谱的获取方式是通过UnityPlayer.currentActivity注意不要缓存这个引用因为Unity的Activity可能会重建。Java层的实现很简单public class IconBridge { public static void switchIcon(String iconName) { Activity activity UnityPlayer.currentActivity; if (activity null) return; // 根据iconName找到对应的alias的ComponentName // 然后调用PackageManager.setComponentEnabledSetting // 具体映射关系可以写一个MapiconName - aliasName } }iconName从Unity传过来时最好用和资源配置一致的字符串比如normal、festival避免两端各一份错误映射。C#层和原生层的字符串约定最好在项目文档里写死不然哪天改名就要排查半天。3.3 切换结果回调与状态同步切换App图标不是同步生效的特别是Android端桌面刷新依赖系统广播iOS端依赖用户点击确认。所以调用接口以后不能立刻告诉游戏逻辑“换完了”必须拿到真实结果再上报。iOS端比较简单直接在completionHandler里拿到error成功失败一目了然。Unity侧的桥接可以用UnitySendMessage把结果传回C#的某个GameObjectextern C void unity_switch_app_icon(const char* iconName) { NSString *name iconName ? [NSString stringWithUTF8String:iconName] : nil; dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] setAlternateIconName:name completionHandler:^(NSError * _Nullable error) { if (error) { UnitySendMessage(AppIconManager, OnSwitchError, [[error localizedDescription] UTF8String]); } else { UnitySendMessage(AppIconManager, OnSwitchSuccess, ); } }]; }); }Android端麻烦一点因为setComponentEnabledSetting这个API本身没有同步回调系统也不承诺告诉你“桌面已经刷新了”。我们实践中会在Java层调用完以后直接返回布尔值表示“切换指令已经成功下发”再定时发送PACKAGE_CHANGED广播。至于桌面最终有没有刷新原生层管不了只能靠埋点数据来统计各机型的表现。C#层收到回调以后要把当前图标状态持久化。我习惯存到PlayerPrefs里至少在游戏下次启动时能明确知道“当前预期图标是哪个”避免在别名没切对的情况下做重复切换反而把桌面图标搞乱。还有一点如果游戏冷启动时检查到本地状态和服务器下发的目标状态不一致会自动再切一次保证最终一致性。3.4 iOS 构建自动化用 Editor 脚本写入备用图标配置iOS侧如果不做自动化每次构建都要手动往Xcode里塞图标资源和plist配置团队出包效率会非常低。建议写一个Editor脚本挂在构建流程后面。核心逻辑是两件事往Info.plist里写CFBundleAlternateIcons把图标文件拷贝到Xcode工程的Assets.xcassets里。大概伪代码思路public class iOSIconPostprocess : IPostprocessBuildWithReport { public int callbackOrder 100; public void OnPostprocessBuild(BuildReport report) { if (report.summary.platform ! BuildTarget.iOS) return; // 1. 修改生成的 Info.plist加入 CFBundleAlternateIcons string plistPath report.summary.outputPath /Info.plist; // 用 PlistDocument 读取和写入 // 2. 把预先放在 Assets/Plugins/iOS/Icons/ 下的图标文件 // 拷贝到 Xcode 工程的 xcassets 中 } }这里不要忘了图片本身也要进Xcode工程。Unity构建时只会把Assets/Plugins/iOS下的源文件拷贝过去不会自动帮你创建AppIcon资源集。所以要么用Editor脚本操作Xcode工程API也可以通过PBXProject要么在原生Xcode侧预留好图片位置。我倾向后者写一个脚本把图片统一拷贝到xcassets/AlternativeIcons目录并自动生成Contents.json。这个自动化流程做完了出包的人不需要懂iOS配置只要把运营要的图标文件按命名规则放进指定目录出包就能自动带上。4. 双端接入实战从工程配置到打包发布4.1 一步步接入指南这里我把整个接入过程整理成一套可以直接照着做的步骤如果你之前的项目完全没做过换图标按这个顺序走一遍基本能通。确定图标位和命名规范。先列出需要的图标样式默认、春节、周年庆、版本大图给每个样式定一个英文标识比如normal、festival_2025、anniv_6th。两端代码里的字符串都用这套命名避免映射混乱。准备图标素材。Android端需要各种密度的mipmap资源mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi至少一套iOS端需要一套覆盖iOS标准尺寸的png图。如果项目已经用Adaptive IconAndroid 8.0以上建议用mipmap-anydpi-v26/ic_icon_xxx.xml这样的自适应图标资源桌面遮罩效果会更好。配置AndroidManifest。把主Activity保留为默认启动入口新增N个activity-alias注意同一时刻只有一个是enabled。这里提醒一句如果主Activity本身也带LAUNCHER入口和alias互斥时一定要在代码里统一控制避免默认入口“永远公开”导致桌面上永远有两个图标。编译AAR并放入Plugins/Android。把Java层的IconBridge打成一个AAR包放到Unity工程的Assets/Plugins/Android下依赖会自动带入。写iOS桥接文件。把.mm文件放进Assets/Plugins/iOS实现unity_switch_app_icon函数并在里面确保dispatch到主线程。写Editor脚本。实现iOS构建后自动修改Info.plist并拷贝图标文件。C#封装层与GameObject回调接收。确保场景里有一个名为AppIconManager的GameObject提前存在否则UnitySendMessage找不到目标会丢消息。本地联调。Android装到真机上手动调用切换观察桌面图标是否变化用adb命令排查有没有异常iOS用TestFlight或Xcode直装点击切换后看弹窗和结果回调。服务器配置与启动检查。如果做运营定时切换在游戏启动时拉取远程配置和目标图标不一致就调用切换接口。4.2 打包发布前必须检查的配置出包前我会把下面这些检查项过一遍基本上能筛掉90%的隐藏问题。Android侧的检查清单AndroidManifest里是否所有alias的targetActivity指向真实存在的Activity类名写错会直接导致启动崩。是否保证同时只有一个LAUNCHER入口enabled。图标资源是否覆盖所有密度目录至少xxxhdpi不能缺。代码中所有“iconName到alias的映射”和服务器配置是否一致大小写敏感。是否处理了Android 8.0以上自适应图标的兼容。iOS侧的检查清单Info.plist里CFBundleAlternateIcons的key是否和代码里传的图标名完全一致。主要图标文件是否全部进包注意Assets.xcassets的Build Phase里要能看到这些资源。setAlternateIconName代码是否在主线程调用。确认备用图标不含混淆信息尤其是App Store审核时可能会让你说明“更换图标”的实际用途。是否有至少一个备用图标且默认图标恢复时传nil的路径也有对应测试。还有平台外部的检查如果你接入了各种SDK统计、热更新、广告要确认这些SDK没有被“换图标切进程”影响尤其是热更新SDK如果在切换瞬间被杀可能导致下次启动补丁异常。建议切换图标的时间点避开热更新拉取的窗口。5. 真机踩坑实录与排查速查表5.1 我踩过的典型坑第一批坑集中在Android桌面刷新上。我用一台小米手机测试时调用切换后桌面图标两分钟都没变代码逻辑看起来完全正常。后来发现是MIUI桌面对PACKAGE_CHANGED广播的响应策略比较激进需要“禁用再启用”触发两次广播才会刷新。我把切换逻辑改成先禁用旧alias等100毫秒再启用新alias部分机型上刷新成功率明显提升。华为EMUI的桌面则喜欢走自己的缓存实测杀掉桌面进程或者锁屏再解锁会刷新。这类问题不建议在代码里做太多“机海战术”适配成本高收益低更好的方案是接受延迟同时把切换时机放在用户不关注icon的时段比如启动后1秒再切。第二批坑是“进程被杀”。早期我在游戏运行中直接调用切换接口很多测试机直接闪退或者冷启动日志里能看到Activity所在任务栈被系统回收。这个问题的根源在于如果用户是从某个alias入口进入游戏的然后你把这个alias disable了系统为了保证入口一致性会结束当前任务。规避办法有两个一是尽量在游戏进入后台或者Splash阶段切换不要在玩法界面裸切二是设置切换完成的标志位如果切换导致冷启动冷启动后通过服务器状态确认是不是已经切到位没有的话补一次。第三批坑是iOS弹窗的“意外”。我们第一次上线iOS换图标功能时运营设计的是“新版本启动时自动换成周年图标”结果玩家陆续反馈桌面弹了一个“是否更换图标”的确认框很多玩家以为是什么系统攻击。后来我们调整了策略不做纯自动切换改成启动后弹一个App内的引导页告诉玩家“长按App图标在快捷菜单里可以切换周年图标”用户有预期了弹窗就不再是惊吓。这里也再次验证了一个结论iOS想做无感自动换图标苹果系统层面就不允许运营需求要想清楚用户体验再提。5.2 常见问题速查表现象可能原因解决办法Android切换后桌面图标长时间不变桌面缓存或未响应PACKAGE_CHANGED广播延迟重新发送广播接受延迟并告知运营有条件可提示用户重启桌面Android桌面出现两个App图标同时有多个LAUNCHER入口处于enabled状态检查各alias和主Activity的enabled状态互斥逻辑禁用全部再启用目标入口Android切换后游戏冷启动禁用了当前正在运行的入口Activity切换时机放到Splash阶段或后台如必须运行中切换可接受冷启动并做状态补偿Android图标切换成功但有些手机没变化国产ROM桌面定制导致不响应做兼容白名单对已知不响应的桌面提供“长按快捷菜单里切换”的备选路径iOS调用setAlternateIconName回报错Info.plist未声明对应图标名或图标资源未进包核对plist key、代码传参、IconFiles里的文件名是否完全一致iOS切换时界面卡顿或崩UIKit调用不在主线程桥接层dispatch_async到主队列再调用用户点击切换按钮无反馈回调没接到或GameObject不存在确认场景中有AppIconManager GameObject检查UnitySendMessage目标名和接收方法名大小写部分Android 8.0以上图标被切图标效果不好没用自适应图标资源改用mipmap-anydpi-v26下的adaptive icon提供前景和背景层iOS恢复默认图标时也弹窗用户困惑系统行为每次setAlternateIconName都会弹窗在引导文案中明确提示切换动画结束后再引导一次这张表是我在实际游戏项目和多个机型上反复试出来的问题清单不敢说能覆盖所有ROM但至少覆盖了90%高频问题。做这个功能最重要的心得是不要试图在原生层解决所有碎片化问题而是把“切换可能不即时生效”这件事当成产品设计的一部分通过引导、缓冲、状态补偿来兜底而不是死磕技术。最后分享一个细节无论Android还是iOS换图标本质上都是在“系统允许的框架内做有限度的表达”它不是一个可以无限折腾的功能。每次大版本迭代前把图标位清单、素材命名、服务器配置项统一检查一遍比到时候临时改要省心得多。这个功能做得顺不顺很多时候在出包前就决定了。
阅读完成 · 觉得有帮助?
咨询建站