事情背景

Android 系统现在是支持 ADB 导出 APK 文件的,也就是安装包。

图为从REALME手机中导出微信APK

小米的工程师 duguowei <duguowei@xiaomi.corp-partner.google.com> 提交了如下2行代码。

大致作用是给读取 APK 文件增加了一个限制条件,在build userdebug或者eng时才能够读取。这样的话,用户只是开启调试模式的话是无法通过 ADB 的 PULL 指令导出 APK 文件的。

他给出的代码作用是“Do not allow shell to obtain data apk”,即不允许 Shell 获取 DATA 目录下的APK 文件,“明面上”给出的理由是:"Apk may include some private resources, so we should not allow others to pull it.",翻译出来就是“APK 可能包含私有的资源,因此我们应该禁止其他人到处APK”。

一位谷歌员工指出了小米提议中的问题,这么做只会阻止普通用户提取 APK 文件,而有一定技术能力的爱好者只需安装一个调试版本的 Android 系统,就可以继续像往常一样提取 APK。按照这种逻辑,谷歌反对小米的保护方法,因为这样做实际上并不能保护任何东西。此外,多名谷歌员工还反对将 APK 文件的内容视为“私人资源”

我的看法

安卓系统发展到今天得益于它的开源和开放,开源主要是指 AOSP,开放则是包含很多东西,其中 APK 可复制和分享也是非常重要的。这一点和 Windows 里面的 EXE 很像,反之则是 iOS 当中必须通过官方应用商店才能下载和安装,用户无法直接安装第三方安装包。

小米员工提交的这两行代码如谷歌员工所说的一样,只是增大了一丢丢从手机导出 APK 的难度,其实意义不大。而如果彻底关闭 APK 导出的渠道并且禁止应用商店之外的渠道安装 APK,恐怕谷歌都要开好多个会,需要高层才能拍板,因为这意味着安卓生态走向了封闭。

duguowei 还提到:

But, I insist on exporting data directly from data partition is unsafe and improper e.g. for those apps which need to be paid to download.(但是,我坚持认为直接从数据分区导出数据是不安全的,不合适的,例如那些需要付费下载的应用程序。)

Google 员工则回复:

Those paid apps usually check if the user has actually paid for the app or the service. For example, by querying the installer of the app, the app can at least know if the app was not sideloaded (adb install) but by Play. It can also ask Google Play to check if the user actually paid for the app or any content in it
这些付费应用程序通常会检查用户是否真的为应用程序或服务付费。例如,通过查询应用程序的安装程序,应用程序至少可以知道应用程序不是侧载(adb安装),而是通过Play。它还可以要求谷歌Play检查用户是否真的为应用程序或其中的任何内容付费。

我认为 duguowei 关于付费下载应用的言论是合理的,国内安卓应用市场几乎没有付费下载的生态,因为没办法判断当前用户是否是付费的。国外的市场依靠 Google Play 可以实现判断安装来源或者设备是否付费,国内:Google Play 是啥?好吃吗?

国内的手机厂商、软件公司和很多独立开发者自然都希望有完善的付费下载应用机制,很可惜,提交的这两行代码是几乎没有任何用处的。

duguowei 还提到了关于APK应用内图片之类的资源泄漏的问题:

some apk include some picutre resources,which can be reused by other people who do not want to design themselves.(一些apk包含一些图片资源,这些资源可以被其他不想自己设计的人重用。)

谷歌员工回复道:图片资源应该靠版权保护。

安卓的 APK 文件其实是一种压缩包,里面的代码可以混淆,但是图片之类的资源确实都可以通过解压 APK 获取到,我也不觉得这是个问题,商业应用谁会去偷别人的图标啊,至于私人 demo 之类的仿写也就无所谓了。

总结

小米的一个员工提交了两行代码,作用是增大普通用户从手机导出APK的难度,因为几乎没啥实际价值而被源码管理者拒绝。我的评价是这不该是小米提出的代码...

因为,不够 Geek。