Android多用户原理和实现 android 点赞实现原理

转载:http://blog.csdn.net/jcgu/article/details/12615661

目录(?)[-]

  1. 多用户模式的启用
  2. 多用户相关操作流程
    1. 用户添加流程
    2. 用户的保存
    3. 用户切换流程
    4. 用户移除流程
  3. 多用户模式的API接口UserManager-UserManagerService
    1. 大致结构
    2. androidosUserManager
    3. isUserAGoat
    4. comandroidserverpmUserManagerService
    5. comandroidserveramActivityManagerService
  4. 多用户模式的牵涉面
    1. 锁屏界面
    2. 外部存储
    3. 包管理PackageManagerService
  5. 可能的发展
    1. Guest用户的实现

在Android 4.2中的一个比较显著的改变就是加入了多用户的支持。因多用户手机专利早已被Symbian雇员注册,故android官方的多用户切换目前仅支持平板设备。

多用户模式的启用

系统判断当前设备是否支持多用户模式的依据是配置文件config.xml中的config_multiuserMaximumUsers配置项。其取值为整型,决定着当前设备支持的最大用户上限。默认值为1,即不支持多用户。如需启用多用户,则设置此值 为大于1的值。在Nexus7中,此值为8

具体代码的判断位置在UserManager.java:

[java]viewplaincopy
  1. publicstaticintgetMaxSupportedUsers(){
  2. //Don'tallowmultipleusersoncertainbuilds
  3. if(android.os.Build.ID.startsWith("JVP"))return1;
  4. returnSystemProperties.getInt("fw.max_users",
  5. Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
  6. }


多用户相关操作流程

对用户的操作目前未对普通应用开放,其相关API都有hide注解,并需要system权限。此外,用户的添加和移除还要需android.Manifest.permission.MANAGE_USERS权限。

用户添加流程

用户添加是通过调用UserManager的public UserInfo createUser(String name, intflags)方法进行的。其具体实现在UserManagerService的同名方法中。

在调用时,系统进行如下操作:

  1. 检查调用者是否具有所需权限。
  2. 对安装和软件包流程加锁,保证线程安全
  3. 检查多用户环境是否到达用户数量限制。如果没有,创建用户实例
  4. 为新用户创建相关目录
  5. 序列化用户列表
  6. 发送用户建立广播,MountService在收到此广播后,调用createEmulatedVolumeForUserLocked方法为用户建立相应的数据目录

用户的保存

用户创建后,会首先在/data/system/users/userlist.xml文件中保存新增加用户的id,创建/data/system/users/用户id目录,并将用户信息保存至其下的用户id.xml文件中。其内容包括一些基本的用户信息。

用户切换流程

用户切换是通过调用ActivityManager的public boolean switchUser(intuserId)方法进行。一般通过 ActivityManagerNative.getDefault().switchUser(intuserId)进行调用。

在调用时,系统进行以下操作

  1. 检查调用者是否具有所需权限。
  2. 获取切换目标用户信息,并设定当前用户为目标用户
  3. WindowsManagerService设置当前用户,锁定屏幕
  1. 切换目标用户状态至启动
  2. 广播REPORT_USER_SWITCH_MSG和USER_SWITCH_TIMEOUT_MSG消息,设定用户切换和切换超时时间(2秒),此超时时间用于限定REPORT_USER_SWITCH_MSG广播全程时间。
  3. 切换Activity堆栈至当前用户
  4. 广播ACTION_USER_SWITCHED消息,各接收组件进行相应操作。 大部分具体操作,比如存储目录切换、安全设置切换等,都在此广播后进行。

用户移除流程

用户移除是通过调用UserManager的 public boolean removeUser(int userHandle)方法进行的。其具体实现同样 是在UserManagerService的同名方法中。

在调用时,系统进行如下操作:

  1. 检查调用者是否具有所需权限。
  2. 对软件包变化加锁
  3. 将用户id加入待移除用户列表,将用户状态设为partial,这样,在下次系统启动时,会清除此用户。
  4. 停止用户,杀掉用户相关进程。
  5. 发送用户移除的广播。广播成功后,删除用户描述文件和数据文件。
  6. 序列化用户列表

此外UserManager还提供了 public void wipeUser(int userHandle)方法,用于删除单个用户的所有数据,但保留 用户账号。 此方法目前对应的底层实现尚未完成。

多用户模式的API接口UserManager->UserManagerService

大致结构

与其它系统服务的实现类似,用户管理也采用了经由Binder调用的远程服务机制。UserManager为暴露给用户的接口,UserManagerService为接口的底层实现。其类图如下所示:

android.os.UserManager

UserManager是暴露出来的应用程序接口。对于普通应用程序,提供用户数查询,用户状态判断和用户序列号查询等基本功能。普通应用没有用户操作权限

对于系统应用,UserManager提供了创建/删除/擦除用户、用户信息获取、用户句柄获取等用户操作的接口。均由远程调用UserManagerService服务的对应方法实现。

isUserAGoat()

UserManager中提供了一个名为isUserAGoat()的方法。源码中此方法直接返回了false。此方法的加入纯粹是为了给枯燥的编程生活带来一丝乐趣,以便写出:

[java]viewplaincopy
  1. while(!isUserAGoat()){
  2. }


这样的语句。

com.android.server.pm.UserManagerService

与其它大部分Service一样,UserManagerService的实现采用了单例模式。在服务中,由组成为UserInfo类的散列表mUsers维护所有的用户状态。

mUsers在系统启动时由/data/system/users/userlist.xml读取生成,并在运行期间动态改变。所有用户的添加、删除操作,都最终序列化回此文件中。

com.android.server.am.ActivityManagerService

ActivityManagerService目前加入了多用户支持。负责维护设备中存在的所有用户状态。服务以下述变量来记录当前处于“启动”状态的用户。

[java]viewplaincopy
  1. finalSparseArraymStartedUsers=newSparseArray();
  2. finalArrayListmUserLru=newArrayList();
  3. int[]mStartedUserArray=newint[]{0};


用户的启动状态对象为com.android.server.am.UserStartedState。其中指定的用户状态有四种:

完整的用户生命周期为:
BOOTING->RUNNING->STOPPING->SHUTDOWN

用户必须处于RUNNING状态时,才能作为切换的目标用户。所以在用户切换流程中,首先要判断当前用户的状态,并启动STOPPING/SHUTDOWN状态的用户。

多用户模式的牵涉面

锁屏界面

用户最先体验到多用户的入口位置即为锁屏界面。锁屏界面中加入了用户切换组件:KeyguardMultiUserSelectorView类。

该类在设备允许多用户存在的情况下,显示当前所有用户的列表。并在用户进行选择后,调用ActivityManagerNative.getDefault().switchUser(intuserId)方法进行用户切换。

外部存储

对于每个用户,Android都为其分配了单独的存储空间。标准的支持多用户的外部存储空间是由init.rc定义的环境变量所指定:

[java]viewplaincopy
  1. #Seestorageconfigdetailsat"http://source.android.com/tech/storage/">http://source.android.com/tech/storage/
  2. mkdir/mnt/shell/emulated0700shellshell
  3. mkdir/storage/emulated0555rootroot
  4. exportEXTERNAL_STORAGE/storage/emulated/legacy
  5. exportEMULATED_STORAGE_SOURCE/mnt/shell/emulated
  6. exportEMULATED_STORAGE_TARGET/storage/emulated
  7. #Supportlegacypaths
  8. symlink/storage/emulated/legacy/sdcard
  9. symlink/storage/emulated/legacy/mnt/sdcard
  10. symlink/storage/emulated/legacy/storage/sdcard0
  11. symlink/mnt/shell/emulated/0/storage/emulated/legacy


Android多用户原理和实现 android 点赞实现原理

在Dalvik虚拟机初始化的过程中,会以dalvik_system_Zygote.cpp中的mountEmulatedStorage函数,使用带有MS_BIND参数的mount命令, 将用户对应的外部存储卡目录mount到上述定义的TARGET目录下。其判断应用userid的方式为:以当前应用的uid/100000,获得对应的userid,这段逻辑位于system/core/libcutils/multiuser.c中。

而Environment类中相应的获取外部存储目录的方法,也是由上述环境变量所获得。对于每个用户,其标准外部存储路径为:

EMULATED_STORAGE_TARGET/userid/

比如:

/storage/emulated/0 为主用户的外部存储路径。

包管理(PackageManagerService)

在多用户环境下,所有用户安装的应用仍然同以前一样,放置于/data/app目录下。但原先/data/data的数据存储位置目前仅对主用户有效,其余用户的数据存储目录则位于/data/user/用户id/目录下。 此目录的创建是在创建用户时由前述的MountService完成的。

对于每个用户,系统都会以PackageuserState类来维护其安装的软件状态。此列表以散列表的形式存在,由PackageSettingBase类维护。所有的包——用户关系和状态最终仍然序列化至/data/system/package.xml中,并保留/data/system/package-backup.xml作为备份。

可能的发展

Guest用户的实现

目前代码中已经存在诸如 isGuestEnabled() 之类的方法。但没有对开发公开,可以预计今后会加入Guest用户,实现“随手玩玩”模式。


  

爱华网本文地址 » http://www.aihuau.com/a/25101011/75448.html

更多阅读

微信点赞统计怎么查看 微信公众平台查看点赞

微信点赞统计怎么查看——简介微信点赞统计怎么查看_微信点赞统计微信点赞统计怎么查看 3、找到“关于微信”微信点赞统计怎么查看 4、微信的“欢迎页”在这边能找到,点击欢迎页面之后就是微信点赞统计。更新版本也可以在这边找到

为浪兄点赞 冲浪兄弟

牧鹅老少年2015-06-29 23:19 删除 编辑回复浪兄为纪念三纺心园2周年,悄不几的来一碗焖肉面犒劳自己。老鹅且把口水咽下,点赞一番。第一,此举弘扬了民族饮食文化。民间有生日吃寿面的习俗,其由来可有漫长的历史了。这个习俗源于西汉

声明:《Android多用户原理和实现 android 点赞实现原理》为网友陷情分享!如侵犯到您的合法权益请联系我们删除