android:sharedUserId作用
前言
Android给每个APK进程分配一个单独的空间,manifest中的userid就是对应一个分配的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者被其他应用程序影响)。
通常,不同的APK会具有不同的userId,因此运行时属于不同的进程中,而不同进程中的资源是不共享的(比如只能访问/data/data/自己包名下面的文件),保障了程序运行的稳定。然后在有些时候,我们自己开发了多个APK并且需要他们之间互相共享资源,那么就需要通过设置shareUserId来实现这一目的。
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中,可以互相访问任意数据。也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件,就像访问本程序的数据一样(使用IPC机制,不同进程之间,比如AIDL)。
shareUserId的属性的最大作用是什么呢?
前面说了,Android中每个app都对应一个uid,每个uid都有自己的一个沙箱,这是基于安全考虑的,那么说到沙箱,我们会想到的是data/data/XXXX/目录下面的所有数据,因为我们知道这个目录下面的所有数据是一个应用私有的,一般情况下其他应用是没有权限访问的,当然root之后是另外情况,这里就不多说了。这里只看没有root的情况,下面我们在来看一个场景:
A应用和B应用都是一家公司的,现在想在A应用中能够拿到B应用存储的一些值,那么这时候该怎么办呢?
这时候就需要用到了shareUserId属性了,但是这里我们在介绍shareUserId属性前,我们先来看一个简单的例子:
使用两个工程:
ShareUserIdPlugin中的MainActivity.java代码如下:
这里很简单,我们使用SharedPreferences来存储一个密码,注意模式是:Context.MODE_PRIVATE,关于模式后面会介绍。
Context提供了几种模式:
- Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND。
- Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
- Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入
其它应用读取该应用目录下此配置文件中passwd肯定是失败的。
如果我们想让A应用访问到B应用的数据,我们可以这么做:把B应用创建模式改成可读模式的,那么A应用就可以操作了,那么这就有一个问题,A应用可以访问了,其他应用也可以访问了,这样所有的应用都可以访问B应用的沙盒数据了,太危险了。
所以要用另外的一种方式,那么这时候就要用到shareUserId属性了,我们只需要将B应用创建方式还是private的,然后A应用和B应用公用一个uid即可,我们下面就来修改一下代码,还是前面的那两个工程,修改他们的AndroidManifest.xml,添shareUserId即可。
这时候,我们发现把代码中的模式改成private的,A应用任然可以访问数据了,其实也好理解,他们两个的uid都相同了,A的文件就是B的,B的就是A的了,他们两个没有沙盒的概念了,数据也是透明的了。
所以这里我们就看到了,使用shareUserId可以达到多个应用之间的数据透明性互相访问。
注意:这里有一个点:这里所有的修改的前提是这个应用的AndroidManifest.xml本身就定义了这个shareUserId,然后我们可以反编译看到这个值,把我们自己的shareUserId改成他的就可以了,但是如果这个应用本身没有这个属性,那么这里就没有办法的,为什么呢,如果要添加,那就是另外一条路了,就是逆向,修改AndroidManifest.xml之后,还需要从新打包在验证,但是这时候没必要了,我们也知道有时候回编译还是很艰难的,如果都能回编译了,那都不需要这些工作了,所以这里需要注意的一个前提。
那么修改之后是不是真的可以呢?
答案是肯定不可以的,如果可以的话,那google也太傻比了,其实Android系统中有一个限制,就是说如果多个应用的uid相同的话,那么他们的apk签名必须一致,不然是安装失败的,如下错误:
通过上面的分析,我们就知道了,Android中是不允许相同的uid的不同签名的应用。
通过shareduserid来获取系统权限
- (1)在AndroidManifest.xml中添加android:sharedUserId="android.uid.system"
- (2)在Android.mk文件里面添加LOCAL_CERTIFICATE := platform(使用系统签名)
- (3)在源码下面进行mm编译
这样生成的apk能够获取system权限,可以在任意system权限目录下面进行目录或者文件的创建,以及访问其他apk资源等(注意创建的文件(夹)只有创建者(比如system,root除外)拥有可读可写权限-rw-------)。
扩展
系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加android:sharedUserId="android.uid.system",然后在Android.mk中增加LOCAL_CERTIFICATE := platform。可以参见Settings等;
系统中所有使用android.uid.shared作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.uid.shared",然后在Android.mk中增加LOCAL_CERTIFICATE := shared。可以参见Launcher等;
系统中所有使用android.media作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.media",然后在Android.mk中增加LOCAL_CERTIFICATE := media。可以参见Gallery等。
android:sharedUserId作用相关推荐
- android:shareduserid获取资源,关于 android:sharedUserId=android.uid.system
先在配置文件AndroidManifest.xml中的manifest里设置,例如: package="com.Demo" android:versionCode="10 ...
- android sharedUserId 共享用户
android:sharedUserId="com.aaa" 相同sharedUserId的app必须使用同一个证书, 被分配同一个uid app安装->sharedUser ...
- 设置android:sharedUserId=android.uid.system 支持 sdcard读写
在AndoridManifest.xml文件中添加android:sharedUserId="android.uid.system" 可以让应用程序获得系统权限,完成很多setti ...
- Android JNI作用及其详解
Android JNI作用及其详解 Java Native Interface (JNI)标准是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 J ...
- android:sharedUserId=android.uid.system 的使用
系统权限使用 android:sharedUserId="android.uid.system" 通过Shared User id,拥有同一个User id的多个APK可以配置成运 ...
- android zxing作用,Android / ZXing不再有效
我的应用程序使用ZXing帮助程序类IntentIntegrator和IntentResult来使用ZXing条形码扫描程序. 现在我发现ZXing不再提交扫描结果,相关的返回值为空/空. 因此,我更 ...
- android handler作用,Android中Handler的作用
* Handler的定义: * 主要接受子线程发送的数据, 并用此数据配合主线程更新UI.当应用程序启动时, * Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控 ...
- android handler作用,3.2.4 Handler的作用
3.2.4 Handler的作用 根据Handler处理Message消息相关特性和前面的实例,可以得出这样的结论:Handler主要作用是异步处理较费时的逻辑,优先将界面返回给用户,异步处理完成后再 ...
- android mvp 作用,Android MVP与MVC的区别和理解
MVC架构: MVC就是Model-View-Controller,它们的作用是: (数据模型)Model:数据的封装和保存,业务逻辑和实体模型 (视图)View:视图界面,对应于布局文件 (控制器) ...
最新文章
- 【Go语言】LiteIDE使用的个人使用方法
- Linux不能上网ping:unknown host问题怎么解决?
- Get Started Part 2
- 多迪技术总监揭秘:PHP为什么是世界上最好的语言?
- python 电脑文件变动提醒_Python整理文件方法,效率提升100倍-docx是什么文件
- android触摸事件触摸点坐标,Android开发——触摸事件TouchEvent详解及其应用
- 今天没白过之《Linux的变量》
- 模拟实现memcpy、memmove函数
- 有一种VR电影比爱情动作片更“爽”
- C语言存储误差,C语言实现测量数据误差处理
- Linux C语言写的超级简单端口扫描器
- Ubunto 16.04设置静态ip地址
- 极兔快递电子面单打印API接口-极兔快递
- Linux Kernel Makefile
- PHP 数字金额转换成中文大写金额的函数 数字转中文
- Cesium 水淹分析
- 计算机维修高级工考试员题库,职业技能鉴定国家题库统一试卷高级计算机维修工知识试题...
- Linux--原子操作(介绍及其操作函数集)
- word2010快速激活
- Keras的Model模型使用
热门文章
- java nifty_Java NiftyDialogBuilder類代碼示例
- halcon 形状匹配
- python连接linux服务器并使用命令_python基于paramiko模块实现远程连接Linux虚拟机(服务器)并执行指定命令返回输出结果...
- c枚举类型enum例题_一篇文章让你详细了解Java中Enum枚举类的使用
- 详解Jedis连接池报错处理
- 006-spring cache-缓存实现-01-原生实现
- ruby Encoding
- 老旧的金融机构,是时候赶赶云计算的时髦了
- 实验记录:vsftp整合mysql-pam管理虚拟账号
- mac easy_install 安装插件失败