**SystemServer.java::ServerThread.run**
~~~
......
//注册AccountManagerService到ServiceManager,服务名为“account”
ServiceManager.addService(Context.ACCOUNT_SERVICE,
newAccountManagerService(context));
~~~
其构造函数的代码如下:
**AccountManagerService.java::AccountManagerService**
~~~
public AccountManagerService(Context context) {
//调用另外一个构造函数,其第三个参数将构造一个AccountAuthenticatorCache对象,它是
//什么呢?见下文分析
this(context,context.getPackageManager(),
new AccountAuthenticatorCache(context));
}
~~~
在AccountManagerService构造函数中创建了一个AccountAuthenticatorCache对象,它是什么?来看下文。
1. AccountAuthenticatorCache分析
AccountAuthenticatorCache是Android平台中账户验证服务(Account AuthenticatorService,AAS)的管理中心。而AAS则由应用程序通过在AndroidManifest.xml中输出符合指定要求的Service信息而来。稍后读者将看到这些要求的具体格式。
先来看AccountAuthenticatorCache的派生关系,如图8-3所示。
:-: ![](http://img.blog.csdn.net/20150803131407976?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-3 AccountAuthenticatorCache类图
由图8-3可知:
- AccountAuthenticatorCache从RegisteredServicesCache<AuthenticatorDescription>派生。RegisteredServicesCache是一个模板类,专门用于管理系统中指定Service的信息收集和更新,而具体是哪些Service由RegisteredServicesCache构造时的参数指定。AccountAuthenticatorCache对外输出由RegisteredServicesCache模板参数指定的类的实例。在图8-3中应该就是AuthenticatorDescription。
- AuthenticatorDescription继承了Parcelable接口,这代表它可以跨Binder传递。该类描述了AAS相关的信息。
- AccountAuthenticatorCache实现了IAccountAuthenticatorCache接口。这个接口供外部调用者使用以获取AAS的信息。
下面看AccountAuthenticatorCache的创建,其相关代码如下:
**AccountAuthenticatorCache.java::AccountAuthenticatorCache**
~~~
public AccountAuthenticatorCache(Context context){
/*
ACTION_AUTHENTICATOR_INTENT值为"android.accounts.AccountAuthenticator"
AUTHENTICATOR_META_DATA_NAME值为"android.accounts.AccountAuthenticator"
AUTHENTICATOR_ATTRIBUTES_NAME值为"account-authenticator"
*/
super(context,
AccountManager.ACTION_AUTHENTICATOR_INTENT,
AccountManager.AUTHENTICATOR_META_DATA_NAME,
AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
}
~~~
AccountAuthenticatorCache调用在其基类RegisteredServicesCache的构造函数时,传递了3个字符串参数,这3个参数用于控制RegisteredServicesCache从PackageManagerService获取哪些Service的信息。
(1) RegisteredServicesCache分析
**RegisteredServicesCache.java::RegisteredServicesCache**
~~~
public RegisteredServicesCache(Context context,String interfaceName,
StringmetaDataName, String attributeName,
XmlSerializerAndParser<V>serializerAndParser) {
mContext= context;
//保存传递进来的参数
mInterfaceName = interfaceName;
mMetaDataName = metaDataName;
mAttributesName = attributeName;
mSerializerAndParser = serializerAndParser;
FiledataDir = Environment.getDataDirectory();
FilesystemDir = new File(dataDir, "system");
//syncDir指向/data/system/registered_service目录
FilesyncDir = new File(systemDir, "registered_services");
//下面这个文件指向syncDir目录下的android.accounts.AccountAuthenticator.xml
mPersistentServicesFile = new AtomicFile(new File(syncDir,
interfaceName+ ".xml"));
//生成服务信息
generateServicesMap();
finalBroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context1, Intent intent) {
generateServicesMap();
}
};
//注册Package安装、卸载和更新等广播监听者
mReceiver = new AtomicReference<BroadcastReceiver>(receiver);
IntentFilter intentFilter = newIntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
mContext.registerReceiver(receiver, intentFilter);
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(receiver, sdFilter);
}
~~~
由以上代码可知:
- 成员变量mPersistentServicesFile指向/data/system/registered_service/目录下的一个文件,该文件保存了以前获取的对应Service的信息。就AccountAuthenticator而言,mPersistentServicesFile指向该目录的android.accounts.AccountAuthenticator.xml文件。
- 由于RegisteredServicesCache管理的是系统中指定Service的信息,当系统中有Package安装、卸载或更新时,RegisteredServicesCache也需要对应更新自己的信息,因为有些Service可能会随着APK被删除而不复存在。
generateServiceMap函数将获取指定的Service信息,其代码如下:
**RegisteredServicesCache.java::generateServicesMap**
~~~
void generateServicesMap() {
//获取PackageManager接口,用来和PackageManagerService交互
PackageManager pm = mContext.getPackageManager();
ArrayList<ServiceInfo<V>> serviceInfos = newArrayList<ServiceInfo<V>>();
/*
在本例中,查询PKMS中满足Intent Action为"android.accounts.AccountAuthenticator"
的服务信息。由以下代码可知,这些信息指的是Service中声明的MetaData信息
*/
List<ResolveInfo> resolveInfos = pm.queryIntentServices(
new Intent(mInterfaceName),PackageManager.GET_META_DATA);
for(ResolveInfo resolveInfo : resolveInfos) {
try {
/*
调用parserServiceInfo函数解析从PKMS中获得的MetaData信息,该函数
返回的是一个模板类对象。就本例而言,这个函数返回一个
ServiceInfo<AccountAuthenticator>类型的对象
*/
ServiceInfo<V> info = parseServiceInfo(resolveInfo);
serviceInfos.add(info);
}
}
synchronized (mServicesLock) {
if(mPersistentServices == null)
readPersistentServicesLocked();
mServices = Maps.newHashMap();
StringBuilder changes = new StringBuilder();
......//检查mPersistentServices保存的服务信息和当前从PKMS中取出来的PKMS
//信息,判断是否有变化,如果有变化,需要通知监听者。读者可自行阅读这段代码,
//注意其中uid的作用
mPersistentServicesFileDidNotExist = false;
}
}
~~~
接下来解析Service的parseServiceInfo函数。
(2) parseServiceInfo函数分析
**RegisteredServicesCache.java::parseServiceInfo**
~~~
private ServiceInfo<V>parseServiceInfo(ResolveInfo service)
throws XmlPullParserException, IOException {
android.content.pm.ServiceInfo si = service.serviceInfo;
ComponentName componentName = new ComponentName(si.packageName, si.name);
PackageManager pm = mContext.getPackageManager();
XmlResourceParser parser = null;
try {
//解析MetaData信息
parser = si.loadXmlMetaData(pm, mMetaDataName);
AttributeSet attrs = Xml.asAttributeSet(parser);
inttype;
......
StringnodeName = parser.getName();
//调用子类实现的parseServiceAttributes得到一个真实的对象,在本例中它是
//AuthenticatorDescription。注意,传递给parseServiceAttributes的第一个
//参数代表MetaData中的resource信息。详细内容见下文的图例
V v=parseServiceAttributes(
pm.getResourcesForApplication(si.applicationInfo),
si.packageName, attrs);
finalandroid.content.pm.ServiceInfo serviceInfo = service.serviceInfo;
finalApplicationInfo applicationInfo = serviceInfo.applicationInfo;
finalint uid = applicationInfo.uid;
returnnew ServiceInfo<V>(v, componentName, uid);
} ...... finally {
if (parser != null) parser.close();
}
}
~~~
parseServiceInfo将解析Service中的MetaData信息,然后调用子类实现的parseServiceAttributes函数,以获取特定类型Service的信息。
下面通过实例向读者展示最终的解析结果。
(3) AccountAuthenticatorCache分析总结
在Email应用的AndroidManifest.xml中定义了一个AAS,如图8-4所示。
:-: ![](http://img.blog.csdn.net/20150803131422504?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-4 Email AAS定义
由图8-4可知,在Email中这个Service对应为EasAuthenticatorService,其Intent匹配的Action为“android.accounts.AccountAuthenticator”,其MetaData的name为“android.accounts.AccountAuthenticator”,而MetaData的具体信息保存在resource资源中,在本例中,它指向另外一个xml文件,即eas_authenticator.xml,此文件的内容如图8-5所示。
:-: ![](http://img.blog.csdn.net/20150803131437028?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-5 eas_authenticator.xml的内容
图8-5为Email中eas_authenticator.xml的内容。这个xml中的内容是有严格要求的,其中:
- accountType标签用于指定账户类型(账户类型和具体应用有关,Android并未规定账户的类型)。
- icon、smallIcon、label和accountPreferences等用于界面显示。例如,当需要用户输入账户信息时,系统会弹出一个Activity,上述几个标签就用于界面显示。详细情况可阅读SDK文档AbstractAccountAuthenticator的说明。
而android.accounts.AccountAuthenticator.xml的内容如图8-6所示。
:-: ![](http://img.blog.csdn.net/20150803131452038?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-6 android.accounts.AccountAuthenticator.xml的内容
由图8-6可知,笔者的测试机器上有3个AAS服务,其中同一个uid有两个服务(即uid为10015对应的两个Service)。
* * * * *
**提示**:uid是在为PackageManagerService解析APK文件时赋予APK的。读者不妨自行阅读frameworks/base/services/java/com/android/server/pm/Settings.java中的newUserIdLPw函数。
* * * * *
下面来看AccountManagerService的构造函数。
2. AccountManagerService构造函数分析
**AccountManagerService.java::AccountManagerService**
~~~
public AccountManagerService(Context context,PackageManager packageManager,
IAccountAuthenticatorCache authenticatorCache) {
mContext= context;
mPackageManager = packageManager;
synchronized (mCacheLock) {
//此数据库文件对应为/data/system/accounts.db
mOpenHelper = new DatabaseHelper(mContext);
}
mMessageThread = new HandlerThread("AccountManagerService");
mMessageThread.start();
mMessageHandler = new MessageHandler(mMessageThread.getLooper());
mAuthenticatorCache = authenticatorCache;
//为AccountAuthenticatorCache设置一个监听者,一旦AAS服务发生变化,
//AccountManagerService需要做对应处理
mAuthenticatorCache.setListener(this, null /* Handler */);
sThis.set(this);
//监听ACTION_PACKAGE_REMOVED广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
publicvoid onReceive(Context context1, Intent intent) {
purgeOldGrants();
}
},intentFilter);
/*
accounts.db数据库中有一个grants表,用于存储授权信息,该信息用于保存哪些Package
有权限获取账户信息。下面的函数将根据grants表中的数据查询PKMS,以判断这些
Package是否还存在。如果系统中已经不存在这些Package,则grants表需要更新
*/
purgeOldGrants();
/*
accounts.db中有一个accounts表,该表中存储了账户类型和账户名。其中,账户类型
就是AuthenticatorDescription中的accountType,它和具体应用有关。下面这个
函数将比较accounts表中的内容与AccountAuthenticatorCache中服务的信息,如果
AccountAuthenticatorCache已经不存在对应账户类型的服务,则需要删除accounts表
中的对应项
*/
validateAccountsAndPopulateCache();
}
~~~
AccountManagerService的构造函数较简单,有兴趣的读者可自行研究以上代码中未详细分析的函数。下面将通过一个具体的例子来分析AccountManagerService的工作流程。
- 前言
- 第1章 搭建Android源码工作环境
- 1.1 Android系统架构
- 1.2 搭建开发环境
- 1.2.1 下载源码
- 1.2.2 编译源码
- 1.2.3 利用Eclipse调试system_process
- 1.3 本章小结
- 第2章 深入理解Java Binder和MessageQueue
- 2.1 概述
- 2.2 Java层中的Binder架构分析
- 2.2.1 Binder架构总览
- 2.2.2 初始化Java层Binder框架
- 2.2.3 addService实例分析
- 2.2.4 Java层Binder架构总结
- 2.3 心系两界的MessageQueue
- 2.3.1 MessageQueue的创建
- 2.3.2 提取消息
- 2.3.3 nativePollOnce函数分析
- 2.3.4 MessageQueue总结
- 2.4 本章小结
- 第3章 深入理解SystemServer
- 3.1 概述
- 3.2 SystemServer分析
- 3.2.1 main函数分析
- 3.2.2 Service群英会
- 3.3 EntropyService分析
- 3.4 DropBoxManagerService分析
- 3.4.1 DBMS构造函数分析
- 3.4.2 dropbox日志文件的添加
- 3.4.3 DBMS和settings数据库
- 3.5 DiskStatsService和DeviceStorageMonitorService分析
- 3.5.1 DiskStatsService分析
- 3.5.2 DeviceStorageManagerService分析
- 3.6 SamplingProfilerService分析
- 3.6.1 SamplingProfilerService构造函数分析
- 3.6.2 SamplingProfilerIntegration分析
- 3.7 ClipboardService分析
- 3.7.1 复制数据到剪贴板
- 3.7.2 从剪切板粘贴数据
- 3.7.3 CBS中的权限管理
- 3.8 本章小结
- 第4章 深入理解PackageManagerService
- 4.1 概述
- 4.2 初识PackageManagerService
- 4.3 PKMS的main函数分析
- 4.3.1 构造函数分析之前期准备工作
- 4.3.2 构造函数分析之扫描Package
- 4.3.3 构造函数分析之扫尾工作
- 4.3.4 PKMS构造函数总结
- 4.4 APK Installation分析
- 4.4.1 adb install分析
- 4.4.2 pm分析
- 4.4.3 installPackageWithVerification函数分析
- 4.4.4 APK 安装流程总结
- 4.4.5 Verification介绍
- 4.5 queryIntentActivities分析
- 4.5.1 Intent及IntentFilter介绍
- 4.5.2 Activity信息的管理
- 4.5.3 Intent 匹配查询分析
- 4.5.4 queryIntentActivities总结
- 4.6 installd及UserManager介绍
- 4.6.1 installd介绍
- 4.6.2 UserManager介绍
- 4.7 本章学习指导
- 4.8 本章小结
- 第5章 深入理解PowerManagerService
- 5.1 概述
- 5.2 初识PowerManagerService
- 5.2.1 PMS构造函数分析
- 5.2.2 init分析
- 5.2.3 systemReady分析
- 5.2.4 BootComplete处理
- 5.2.5 初识PowerManagerService总结
- 5.3 PMS WakeLock分析
- 5.3.1 WakeLock客户端分析
- 5.3.2 PMS acquireWakeLock分析
- 5.3.3 Power类及LightService类介绍
- 5.3.4 WakeLock总结
- 5.4 userActivity及Power按键处理分析
- 5.4.1 userActivity分析
- 5.4.2 Power按键处理分析
- 5.5 BatteryService及BatteryStatsService分析
- 5.5.1 BatteryService分析
- 5.5.2 BatteryStatsService分析
- 5.5.3 BatteryService及BatteryStatsService总结
- 5.6 本章学习指导
- 5.7 本章小结
- 第6章 深入理解ActivityManagerService
- 6.1 概述
- 6.2 初识ActivityManagerService
- 6.2.1 ActivityManagerService的main函数分析
- 6.2.2 AMS的 setSystemProcess分析
- 6.2.3 AMS的 installSystemProviders函数分析
- 6.2.4 AMS的 systemReady分析
- 6.2.5 初识ActivityManagerService总结
- 6.3 startActivity分析
- 6.3.1 从am说起
- 6.3.2 AMS的startActivityAndWait函数分析
- 6.3.3 startActivityLocked分析
- 6.4 Broadcast和BroadcastReceiver分析
- 6.4.1 registerReceiver流程分析
- 6.4.2 sendBroadcast流程分析
- 6.4.3 BROADCAST_INTENT_MSG消息处理函数
- 6.4.4 应用进程处理广播分析
- 6.4.5 广播处理总结
- 6.5 startService之按图索骥
- 6.5.1 Service知识介绍
- 6.5.2 startService流程图
- 6.6 AMS中的进程管理
- 6.6.1 Linux进程管理介绍
- 6.6.2 关于Android中的进程管理的介绍
- 6.6.3 AMS进程管理函数分析
- 6.6.4 AMS进程管理总结
- 6.7 App的 Crash处理
- 6.7.1 应用进程的Crash处理
- 6.7.2 AMS的handleApplicationCrash分析
- 6.7.3 AppDeathRecipient binderDied分析
- 6.7.4 App的Crash处理总结
- 6.8 本章学习指导
- 6.9 本章小结
- 第7章 深入理解ContentProvider
- 7.1 概述
- 7.2 MediaProvider的启动及创建
- 7.2.1 Context的getContentResolver函数分析
- 7.2.2 MediaStore.Image.Media的query函数分析
- 7.2.3 MediaProvider的启动及创建总结
- 7.3 SQLite创建数据库分析
- 7.3.1 SQLite及SQLiteDatabase家族
- 7.3.2 MediaProvider创建数据库分析
- 7.3.3 SQLiteDatabase创建数据库的分析总结
- 7.4 Cursor 的query函数的实现分析
- 7.4.1 提取query关键点
- 7.4.2 MediaProvider 的query分析
- 7.4.3 query关键点分析
- 7.4.4 Cursor query实现分析总结
- 7.5 Cursor close函数实现分析
- 7.5.1 客户端close的分析
- 7.5.2 服务端close的分析
- 7.5.3 finalize函数分析
- 7.5.4 Cursor close函数总结
- 7.6 ContentResolver openAssetFileDescriptor函数分析
- 7.6.1 openAssetFileDescriptor之客户端调用分析
- 7.6.2 ContentProvider的 openTypedAssetFile函数分析
- 7.6.3 跨进程传递文件描述符的探讨
- 7.6.4 openAssetFileDescriptor函数分析总结
- 7.7 本章学习指导
- 7.8 本章小结
- 第8章 深入理解ContentService和AccountManagerService
- 8.1 概述
- 8.2 数据更新通知机制分析
- 8.2.1 初识ContentService
- 8.2.2 ContentResovler 的registerContentObserver分析
- 8.2.3 ContentResolver的 notifyChange分析
- 8.2.4 数据更新通知机制总结和深入探讨
- 8.3 AccountManagerService分析
- 8.3.1 初识AccountManagerService
- 8.3.2 AccountManager addAccount分析
- 8.3.3 AccountManagerService的分析总结
- 8.4 数据同步管理SyncManager分析
- 8.4.1 初识SyncManager
- 8.4.2 ContentResolver 的requestSync分析
- 8.4.3 数据同步管理SyncManager分析总结
- 8.5 本章学习指导
- 8.6 本章小结