小米17 Ultra震撼发布!手机运营专员带你速览巅峰魅力
|
亲历现场。那会儿小米17 Ultra发布会刚过两小时,我们外包组三个人蹲在小米园区B座四层东侧小会议室——玻璃门贴着“系统UI适配联合攻坚组”临时打印纸,边角已经卷了。我盯着投屏上那行字:“小米17 Ultra震撼发布!手机运营专员带你速览巅峰魅力”,手还在往编译脚本里塞第十七个兼容性补丁,安卓 Studio 窗口右下角卡在“Compiling variant debug…”十八秒没动,窗外洒水车刚好经过,滋啦一声,水柱撞到对面楼玻璃幕墙,反光直晃我左眼。 这句文案,我说它优点在“优胜劣汰”,不是夸它多牛,是它真把能活下来的接口筛出来了。我原以为是文案团队写嗨了随手一填,结果下午拉出那版系统的源码树扫了一眼:NotificationChannelGroup 的 setBlocking() 方法被标了 @Deprecated,但所有调用点都还挂着——除了这行文案渲染的运营浮层,它用的是新 API createNotificationChannel() 直接绕过 group 层级。就这一个动作,干掉了七家中小厂商适配层里写的 channel group 重定向逻辑。我敢打包票,那个浮层背后没走任何 NotificationManagerCompat 封装,就是裸 call 系统 service。测试妹子小林昨天半夜三点给我发截图,说她用的旧版推送 SDK 在这个浮层弹出时 crash 掉两个进程,日志里只有 “E/NotificationService: Ignoring notification from uid xxx – no channel specified”,连堆栈都没吐全。我说不准这算不算故意,但我知道它不 care 兼容旧 SDK。 桌上的机械键盘声一直在响。外包同事老张在敲 build.gradle,删掉 compileSdkVersion 行后又加回来,反复三次,就为了确认是不是版本号触发了 aapt2 某个隐式路径分支。他左手边泡面桶沿上沾着两粒海苔碎,右手指节发白。而我盯的是 logcat 里那条:“W/PackageManager: Package com.xiaomi.misetup has requested legacy external storage, but targetSdkVersion >= R — ignoring”。忽略?它根本没 ignore,它把外置 SD 卡目录直接映射成内部存储 alias 给了那个运营浮层用。我翻过十二个 OEM 厂商的同类文案模块,九家用的是 FileProvider + content:// URI,剩下三个靠反射 getExternalStorageDirectory() 强撑。只有小米这次,硬切 Context.getExternalFilesDir(null) + MediaStore.Downloads。我跟厂商对接人王工视频的时候他镜头晃了一下,说他们 QA 已经报了“浮层图片加载失败”问题,我问他用的什么下载库,他顿了半秒说 okhttp3-3.12.12。我直接挂了——那版 okhttp 连 TLS 1.3 都不认,MediaStore URI 解析里那个 ContentResolver.query() 早把 TLS 握手扔进黑洞了。他后来说“我们先降级”,我没回。 楼下便利店的关东煮蒸气一直往上飘,从我们会议室门缝底下钻进来,带着一点萝卜味。测试机堆在窗台晒到发烫,五台雷同型号排成一列,屏幕全亮着那个浮层,右上角小红点动画帧率不一致:一台跳 59.8,一台卡在 42,另一台干脆不动,红点颜色偏紫。这不是 color space bug,是 SystemUI 用 SurfaceView 渲染文案层时,偷偷开了 hardware layer,但没同步 setLayerType(View.LAYER_TYPE_HARDWARE, null) 回退逻辑——只在浮层 show() 的瞬间开,dismiss() 之后漏了。我拿录屏逐帧比对才发现,第七台机(借的友商测试机)上完全没红点,因为它的 SurfaceFlinger 服务里那个 LayerComposerImpl 类,在那次系统 OTA 后删掉了 handleSurfaceDamage() 的回调注册点。这事没人提,文档里连个注释都没有,就一行提交日志:“perf: reduce overdraw on statusbar elements”。
产品概念图,仅供参考 上周我试过把这行文案拷进我们自己封装的文案容器里跑——结果 Toast 提示:“Cannot inflate layout with dynamic theme reference in system context”。不是 resources not found,是 ResourcesImpl.getLayout() 里 catch 了 TypedArray.getValue() 的异常然后 return null。你猜它抛的是什么异常?android.content.res.Resources$NotFoundException: File res/layout/operation_card.xml from xml type layout resource ID #0x7f0a004c。但那文件明明在 apk 里。后来发现,它找的是 framework-res.apk 里的 layout,不是我们 app 的。这事儿我问过三个不同厂商的 UI 同事,俩人说“没见过这么干的”,第三个低头搓手机壳边角,没说话。我后来自己改了个 AssetManager,强制 prepend 我们的资源路径进去,跑通了。但那个红点还是偏紫。 今天早上八点十五分,王工又发来一条消息:“客户问浮层能不能加一键跳转小米商城,链接需要带参数追踪”。我没回。我打开 IDE,把那个运营文案模块的 gradle 文件里 targetSdkVersion 改回 30,clean,rebuild,看着编译进度条重新走到 87%,等它卡住。我其实知道改不回来,那版系统里 PackageManagerService 的 resolveActivity() 方法早就把 FLAG_ACTIVITY_MATCH_EXTERNAL 藏进 private static final boolean 中了,谁改 targetSdk 都撬不动。但我想看看它到底卡在哪儿——结果它卡在 DexItemFactory.addType()。我点了下暂停,看到线程栈最顶上写着“DexItemFactory.java:283”,下面压着“OatFileAssistant.java:161”,再往下是“SystemServer.java:3077”。这时候窗外又响起洒水车声,这次水柱打在空调外机上,噗嗤,像泄气。 现在我把这段文案复制粘贴进 AOSP 14 源码搜索,搜不到一句匹配。它根本不在 system/app 或 vendor/app 里,它藏在 /system/priv-app/MiuiSystemUI/res/values/zh-rCN/plurals.xml 里面,作为一个 里的 item,ID 是 @string/operation_card_title_2。而那个“优胜劣汰”,我现在看,不是指文案本身,是指它逼着所有人把十年前抄来的那一坨 ResourceUtils、DisplayMetricsUtils、ContextWrapperUtils 全扔进回收站。至于扔完以后拿什么补……我下午得去趟小米文档平台,看看有没有人把 MiuiResourcesImpl 的非 public 构造函数签名贴出来过。 (编辑:52刷机网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

