LeoYan Blog

技术分享,生活记录。

0%

Android 如何用 sharedUserId 做数据共享

转载请注明出处:www.leoyanblog.com

本文出自 LeoYan 的博客

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 LeoYan 即可关注。

背景

当 APK 安装的时候,userId 这个标志就会产生。APK 在设备上的整个生命周期中,这个 ID 不再改变。同一个应用包在不同设备上可能有不同的 userId,重要的是在给定的设备上,每个应用包有自己独立的 userId。

userId的特点

  1. 作为 APK 身份的标识

  2. userId 对应一个 Linux 用户,所以不同 APK (用户)间互相访问数据默认是禁止的。

那么不同 APK 之间想要互相访问数据应该怎么办呢?

数据共享

Android 为我们提供了两种数据互访的方法:

  1. 使用 Share Preference / Content Provider

APK通过指定接口和数据供其它APK读取,开发者需要实现接口和指定 share 的数据。

  1. 在配置文件 manifest 中配置相同的 UserId

通过共享 userId,拥有相同 userId 的用户可以配置成运行在同一进程当中,因此默认就是可以互相访问任意数据的。

也可以配置为不同进程当中,彼此之间就像访问自己的数据一样访问彼此的数据库和文件。

例子

应用1:com.leoyanblog.sqlite

1
2
3
4
5
6
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.leoyanblog.sqlite"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="leoyanblog.com"
>

应用2:com.leoyanblog.activity

1
2
3
4
5
6
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.leoyanblog.activity"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="leoyanblog.com"
>

这两个应用的 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 共享数据需要满足以下条件:

  1. APK 的签名必须相同

  2. android:shareUserId 的值必须相同

  3. 如果想要运行在同一个进行当中,必须设置 android:process 的值相同。

application 设置应用程序的全部组件都运行在某个线程中

1
2
3
4
5
6
<application 
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:process="leoyan.com">