转载请注明出处:www.leoyanblog.com
本文出自 LeoYan 的博客
本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 LeoYan 即可关注。
背景
当 APK 安装的时候,userId 这个标志就会产生。APK 在设备上的整个生命周期中,这个 ID 不再改变。同一个应用包在不同设备上可能有不同的 userId,重要的是在给定的设备上,每个应用包有自己独立的 userId。
userId的特点
作为 APK 身份的标识
userId 对应一个 Linux 用户,所以不同 APK (用户)间互相访问数据默认是禁止的。
那么不同 APK 之间想要互相访问数据应该怎么办呢?
数据共享
Android 为我们提供了两种数据互访的方法:
- 使用 Share Preference / Content Provider
APK通过指定接口和数据供其它APK读取,开发者需要实现接口和指定 share 的数据。
- 在配置文件 manifest 中配置相同的 UserId
通过共享 userId,拥有相同 userId 的用户可以配置成运行在同一进程当中,因此默认就是可以互相访问任意数据的。
也可以配置为不同进程当中,彼此之间就像访问自己的数据一样访问彼此的数据库和文件。
例子
应用1:com.leoyanblog.sqlite
1 | <manifestxmlns:android="http://schemas.android.com/apk/res/android" |
应用2:com.leoyanblog.activity
1 | <manifestxmlns:android="http://schemas.android.com/apk/res/android" |
这两个应用的 userId 相同,都为”leoyanblog.com”,因此两个应用共享 userId,如果应用1想访问应用2的数据怎么办呢?
1 | Content content = this.createPackageContent(“com.leoyanblog.activity”, Content.CONTENT_IGNORE_SECURITY); |
这样通过 content 可以获取到应用2中的资源,包括:数据库,preference,资源文件等。
注意:
基于安全考虑,两个 package 需要有相同的签名。否则如果没有验证,应用程序一旦设置了 sharedUserId,当程序被破解,其它应用也可以访问我们的数据。数据不安全设置共享也就没有多大意义了。
总结
如果想要不同的 APK 之间,通过 sharedUserId 共享数据需要满足以下条件:
APK 的签名必须相同
android:shareUserId 的值必须相同
如果想要运行在同一个进行当中,必须设置 android:process 的值相同。
application 设置应用程序的全部组件都运行在某个线程中
1 | <application |