**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所示。
:-: 
圖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所示。
:-: 
圖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所示。
:-: 
圖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所示。
:-: 
圖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 本章小結