1 前言
公司做游戏的同事问了安装同一套代码不同包名的 apk,第二个安装的 apk 总是不能安装成功的问题,第一感觉是觉得不可能,拿到他给的 apk,使用 adb 命令安装后,发现了报错:
C:\Users\wangzhichao\Desktop>adb install C:\Users\wangzhichao\Desktop\The9_cli-release.apk
adb: failed to install C:\Users\wangzhichao\Desktop\The9_cli-release.apk: Failure [INSTALL_FAILED_CONFLICTING_PROVIDER: Package couldn't be installed in /data/a
pp/com.abc.the88a-2cdGt6dij9W8Pr6GpSXcMQ==: Can't install because provider name com.facebook.app.FacebookContentProvider2128815847340775 (in package com.
abc.the88a) is already used by com.abc.the88]
2 分析
2.1 看报错信息
从报错信息可以看出:com.abc.the88a 这个包不能安装的原因是它里面有一个名字是 com.facebook.app.FacebookContentProvider2128815847340775 的 provider 已经被 com.abc.the88 使用了。
查看代码了解到,因为是一套代码,确实是共用了这个 provider,不过 com.facebook.app.FacebookContentProvider2128815847340775 对应的是 android:authorities 的值。
2.2 验证复现
使用同一份包含 Provider 的 代码,不同的包名打两个包,可以复现问题:
把 Provider 的 authorities 修改成不一样的后,可以安装成功。
2.3 为什么不能重复呢?
查看官方文档(docs/guide/topics/manifest/provider-element.html)的描述:
The Android system stores references to content providers according to an authority string, part of the provider’s content URI.
Android 系统根据 authority 字符串来储存 ContentProvider 的引用,并且 authority 还是 contentURI 的一部分。从这句话可以得出,在 Android 中 authority 必须是唯一的,不然 Android 系统如何区分开不同应用的 ContentProvider 呢?
2.4 该如何规避这个问题?
当命名 authorities 的时候,在前面加上自己的 applicationId,这是一种有效的方法,也是一种最佳实践。