无论是 Android 还是 iOS 系统,每隔一段时间就会出现奇怪的 Bug 导致手机卡死甚至不断重启无法开机。Bug 的元凶有时候是奇怪的 Emoji,有时候是其他国家比较少见的文字导致的排版问题,而最近 Android 系统碰上了新「玩法」:只要你把这张图片设为壁纸,手机就会不断重启,甚至会清空手机数据(所以千万不要尝试)!
这张图片已经过处理,不会导致死机
Bug 症状
就是上面这张图片最近在推特、微博等平台广为流传,最初人们都把它当做是玩笑,但部分不信邪的用户「作死」后纷纷发出自己手机的惨状。他们中有屏幕不断闪烁的,有直接进入 Recovery 恢复模式的,甚至有直接清空数据恢复出厂的,后果可谓非常严重。这其中又以谷歌和三星手机数量最多,详细的原因后面我们会谈到。
中招的手机
这张壁纸是裁剪成手机比例的图片,分辨率为 1440*2560。我们用谷歌搜索这张图片,会发现相似图片里面有横屏的原图,再次搜索这张原图则只有 4 个结果,对比可以发现这张图最早由 hdqwallpaper 上的一位摄影师拍摄上传。我们把原图下载下来之后查看 EXIF 信息,可以看到这只是张普通的风景照。
摄影师拍摄的原图
非常神奇的地方在于,把这张原图设为手机壁纸也会导致手机屏幕闪烁重启,这样排除了有人在裁剪后的手机比例图片上做手脚的可能,是图片本身的问题。但在相册里查看图片,把图片截图后再设为壁纸都不会有任何不好的后果。
Bug 原因
那么这个奇怪的壁纸 Bug 是怎么产生的呢?著名 YouTuber Mrwhosetheboss 花了三天时间找到了答案:照片上的一个像素令 Android 颜色管理库压缩色域时产生了错误,从而导致 SystemUI 崩溃。Mrwhosetheboss 甚至还找到了这个像素:
导致错误的像素,来源:Mrwhosetheboss
Android 原生自带的颜色管理库只支持 sRGB 色域(Android 8.0 之后支持广色域管理,但必须开发者手动给应用 Activity 启用才行),而通过图片查看软件我们可以看到这次产生 Bug 的照片本身是 ProPhoto RGB 色域,两个色域的关系可以看下面这个图:
两个色域的对比,来源:维基百科
我在《显示器完全指南》的第一章(可免费试读)中有讲解过色域,简单来说就是色域表示显示设备能显示的颜色范围,采用相同色域的显示器能够比较好地显示/打印相同的效果,避免同一张图片在不同显示设备中颜色不同。
这样 Android 手机想要把图片正常显示就必须把比较广的 ProPhoto RGB 色域通过算法压缩到 sRGB 色域,因此会导致图片颜色变淡,我们可以通过微博上传刚刚下载的原始图片来查看转换效果(因为微博也不支持 ProPhoto RGB 图片),正因为如此微博上下载的这张图一般也搞坏不了你的 Android 手机。
微博上传效果
当压缩到上面提到的那一个像素时问题就出现了,按照系统自带转换像素亮度的算法,像素亮度共有(0-255)256 个阶级,这个像素转换之后像素亮度应该是 254:
转换算法与转换后的像素亮度
但为了避免最后的数字是浮点数(小数),这个算法好死不死有个取整数步骤,把红绿蓝三个子像素取整到下一个整数,这样加起来最后得到了 256 这个并不存在的像素亮度:
取整后的像素亮度
于是系统就不知道该怎么应对这种没见过的情况,加上谷歌本身并没有为这种情况写好解决方法,所以程序就会抛出(try)错误,同时由于没有捕捉(catch)到错误于是颜色管理部库在的 SystemUI 系统界面便会崩溃,便产生了我们看到的不断闪屏和系统自救进入的 Recocery 模式。
这个 Bug 的产生,只是因为一张图片上一个像素与算法的「巧妙结合」。其实手机系统异常复杂,总有些边边角角会导致各种奇怪的问题,但发现问题后修复也很简单,我和 Mrwhosetheboss 还有其它知道原因的人,第一反应就能得出解决方法,只要给转换后的像素亮度加一个 if 判断,大于 255 就设置为 255 就可以了。
这也解释了为什么很多国产手机和魔改了 Android 系统的手机能够「免疫」这个问题,他们的程序员或是因为要实现广色域管理等原因重写了颜色管理库,也有可能顺手加上了一个 if 判断,从而避免了错误的发生。
解决方法
很多「手贱」的用户最后不得不舍弃自己手机上的数据恢复出厂设置,或者直接送去手机店修理,但其实我们还有方法可以拯救中招的手机。
开机后趁屏幕黑屏时双击电源键打开相机,接着长按开机键出现电源菜单,长按关机/重启会弹出安全模式提示,确认后手机会自动重启进入安全模式。
进入安全模式
如果手机没有电源键双击打开相机功能或者开机后无法操作,可以开机时一直按住音量键(上/下,有些手机需要按特定次数,可以用搜索引擎搜索「机型 + 安全模式」),这样手机便会进入安全模式。
进入安全模式之后壁纸会变成默认的,这个时候手机便可以正常操作。我们解锁手机,打开系统设置 → 应用 → 应用管理,在应用列表中找到我们的默认桌面和锁屏(如果有的话,有些手机需要在右上角选择「显示系统应用」),把它们的应用数据清除。
清除相关应用数据
这样我们会丢失掉桌面布局等桌面数据,但正常重启之后壁纸会变成手机默认壁纸,这样一台中招的手机就抢救回来了。
小结
手机系统是非凡软件工程成就,里面错综复杂,即使大公司拥有千千万万的工程师也无法面面俱到。每隔一段时间肯定会有新的奇怪玩意导致我们手机出问题,所以平时我们在上网的时候要注意管住自己的好奇心,不要轻易尝试转发、复制、下载各种奇怪的字符/Emoji/图片,不然很可能就要和自己爱机上的数据说拜拜了。