SyncManager的構造函數的代碼較長,可分段來看。下面先來介紹第一段的代碼。
1. SyncManager介紹
**SyncManager.java::SyncManager**
~~~
public SyncManager(Context context, booleanfactoryTest) {
mContext= context;
//SyncManager中的幾位重要成員登場。見下文的解釋
SyncStorageEngine.init(context);
mSyncStorageEngine =SyncStorageEngine.getSingleton();
mSyncAdapters = newSyncAdaptersCache(mContext);
mSyncQueue = newSyncQueue(mSyncStorageEngine, mSyncAdapters);
HandlerThread syncThread = newHandlerThread("SyncHandlerThread",
Process.THREAD_PRIORITY_BACKGROUND);
syncThread.start();
mSyncHandler = new SyncHandler(syncThread.getLooper());
mMainHandler = new Handler(mContext.getMainLooper());
/*
mSyncAdapters類似AccountManagerService中的AccountAuthenticatorCache,
它用于管理系統中和SyncService相關的服務信息。下邊的函數為mSyncAdapters增加一個
監聽對象,一旦系統中的SyncService發生變化(例如安裝了一個提供同步服務的APK包),則
SyncManager需要針對該服務發起一次同步請求。同步請求由scheduleSync函數發送,
后文再分析此函數
*/
mSyncAdapters.setListener(new
RegisteredServicesCacheListener<SyncAdapterType>() {
public void onServiceChanged(SyncAdapterType type,
boolean removed) {
if (!removed) {
scheduleSync(null, type.authority, null, 0,false);
}
}
},mSyncHandler);
~~~
在以上代碼中,首先見到的是SyncManager的幾位重要成員,它們之間的關系如圖8-11所示。
:-: 
圖8-11 SyncManager成員類圖
由圖8-11可知, SyncManager的這幾位成員的功能大體可分為3部分:
- 左上角是SyncAdaptersCache類,從功能和派生關系上看,它和AccountManagerService中的AccountAuthenticatorCaches類似。SyncAdaptersCache用于管理系統中SyncService服務的信息。在SyncManager中,SyncService的信息用SyncAdapterType類來表示。
- 左下角是SyncQueue和SyncOperation類,SyncOperation代表一次正在執行或等待執行的同步操作,而SyncQueue通過mOperationsMap保存系統中存在的SyncOperation。
- 右半部分是SyncStorageEngine,由于同步操作涉及,重要數據的傳輸,加之可能耗時較長,所以SyncStorageEngine提供了一些內部類來保存同步操作中的一些信息。例如PendingOperation代表保存在從本地文件中的那些還沒有執行完的同步操作的信息。另外,SyncStrorageEngine還需要對同步操作進行一些統計,例如耗電量統計等。SyncStorageEngine包含的內容較多,讀者學習完本章后可自行研究相關內容。
SyncManager家族成員的責任分工比較細,后續分析時再具體討論它們的作用。先接著看SyncManager的構造函數:
**SyncManager.java::SyncManager**
~~~
......
//創建一個用于廣播發送的PendingIntent,該PendingIntent用于和
//AlarmManagerService交互
mSyncAlarmIntent= PendingIntent.getBroadcast(
mContext, 0, new Intent(ACTION_SYNC_ALARM),0);
//注冊CONNECTIVITY_ACTION廣播監聽對象,用于同步操作需要使用網絡,所以
//此處需要監聽和網絡相關的廣播
IntentFilter intentFilter =
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
if(!factoryTest) {
//監聽BOOT_COMPLETED廣播
intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
context.registerReceiver(mBootCompletedReceiver, intentFilter);
}
//監聽BACKGROUND_DATA_SETTING_CHANGED廣播。該廣播與是否允許后臺傳輸數據有關,
//用戶可在Settings應用程序中設置對應選項
intentFilter =
new IntentFilter(ConnectivityManager.
ACTION_BACKGROUND_DATA_SETTING_CHANGED);
context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
//監視設備存儲空間狀態廣播。由于SyncStorageEngine會保存同步時的一些信息到存儲
//設備中,所以此處需要監視存儲設備的狀態
intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
context.registerReceiver(mStorageIntentReceiver, intentFilter);
//監聽SHUTDOWN廣播。此處設置優先級為100,即優先接收此廣播
intentFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
intentFilter.setPriority(100);
context.registerReceiver(mShutdownIntentReceiver, intentFilter);
if(!factoryTest) {//和通知服務交互,用于在狀態欄上提示用戶
mNotificationMgr = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
//注意,以下函數注冊的廣播將針對前面創建的mSyncAlarmIntent
context.registerReceiver(new SyncAlarmIntentReceiver(),
newIntentFilter(ACTION_SYNC_ALARM));
}......
mPowerManager = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
//創建WakeLock,防止同步過程中掉電
mHandleAlarmWakeLock =
mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
HANDLE_SYNC_ALARM_WAKE_LOCK);
mHandleAlarmWakeLock.setReferenceCounted(false);
mSyncManagerWakeLock =
mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
SYNC_LOOP_WAKE_LOCK);
mSyncManagerWakeLock.setReferenceCounted(false);
//知識點一:監聽SyncStorageEngine的狀態變化,如下文解釋
mSyncStorageEngine.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
newISyncStatusObserver.Stub() {
public void onStatusChanged(int which) {
sendCheckAlarmsMessage();
}
});
//知識點二:監視賬戶的變化。如果用戶添加或刪除了某個賬戶,則需要做相應處理。
//如下文解釋
if(!factoryTest) {
AccountManager.get(mContext).addOnAccountsUpdatedListener(
SyncManager.this,
mSyncHandler, false);
onAccountsUpdated(AccountManager.get(mContext).getAccounts());
}
}
~~~
在以上代碼中,有兩個重要知識點。
- 第一, SyncManager為SyncStorageEngine設置了一個狀態監聽對象。根據前文的描述,在SyncManager家族中,SyncStorageEngine專門負責管理和保存同步服務中絕大部分的信息,所以當外界修改了這些信息時,SyncStorageEngine需要通知狀態監聽對象。我們可以通過一個例子了解其中的工作流程。下面的setSyncAutomatically函數的作用是設置是否自動同步某個賬戶的某項數據,代碼如下:
**ContentService.java::setSyncAutomatically**
~~~
public void setSyncAutomatically(Account account,String providerName,
booleansync) {
......//檢查WRITE_SYNC_SETTINGS權限
longidentityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
if(syncManager != null) {
/*
通過SyncManager找到SyncStorageEngine,并調用它的
setSyncAutomatically函數。在其內部會修改對應賬戶的同步服務信息,然后通知
監聽者,而這個監聽者就是SyncManager設置的那個狀態監聽對象
*/
syncManager.getSyncStorageEngine().setSyncAutomatically(
account, providerName,sync);
}
}finally {
restoreCallingIdentity(identityToken);
}
}
~~~
在以上代碼中,最終調用的是SyncStorageEngine的函數,但SyncManager也會因狀態監聽對象被觸發而做出相應動作。實際上,ContentService中大部分設置同步服務參數的API,其內部實現就是先直接調用SyncStorageEngine的函數,然后再由SyncStorageEngine通知監聽對象。讀者在閱讀代碼時,仔細一些就可明白這一關系。
- 第二,SyncManager將為AccountManager設置一個賬戶更新監聽對象(注意,此處是AccountManager,而不是AccountManagerService。AccountManager這部分功能的代碼不是很簡單,讀者有必要反復研究)。在Android平臺上,數據同步和賬戶的關系非常緊密,并且同一個賬戶可以對應不同的數據項。例如在EasAuthenticator的addAccount實現中,讀者會發現一個Exchange賬戶可以對應Contacts、Calendar和Email三種不同的數據項。在添加Exchange賬戶時,還可以選擇是否同步其中的某項數據(通過判斷實現addAccount時傳遞的options是否含有對應的同步選項,例如同步郵件數據時需要設置的OPTIONS_EMAIL_SYNC_ENABLED選項)。由于SyncManager和賬戶之間的這種緊密關系的存在,SyncManager就必須監聽手機中賬戶的變化情況。
* * * * *
**提示**:上述兩個知識點涉及的內容都是一些非常細節的問題,本章擬將它們作為小任務,讀者可自行研究它們。
* * * * *
下面來認識一下SyncManager家族中的幾位主要成員,首先是SyncStorageEngine。
2. SyncStorageEngine介紹
SyncStorageEngine負責整個同步系統中信息管理方面的工作。先看其init函數代碼:
**SyncStorageEngine.java::init**
~~~
public static void init(Context context) {
if(sSyncStorageEngine != null) return;
/*
得到系統中加密文件系統的路徑,如果手機中沒有加密的文件系統(根據系統屬性
“persist.security.efs.enabled”的值來判斷),則返回的路徑為/data,
目前的Android手機大部分都沒有加密文件系統,故dataDir為/data
*/
FiledataDir = Environment.getSecureDataDirectory();
//創建SyncStorageEngine對象
sSyncStorageEngine = new SyncStorageEngine(context, dataDir);
}
~~~
而SyncStorageEngine的構造函數代碼為:
**SyncStorageEngine.java::SyncStorageEngine**
~~~
private SyncStorageEngine(Context context, FiledataDir) {
mContext= context;
sSyncStorageEngine = this;
mCal =Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
FilesystemDir = new File(dataDir, "system");
FilesyncDir = new File(systemDir, "sync");
syncDir.mkdirs();
//mAccountInfoFile指向/data/system/sync/accounts.xml
mAccountInfoFile = new AtomicFile(new File(syncDir,"accounts.xml"));
//mStatusFile指向/data/system/sync/status.bin,該文件記錄
//一些和同步服務相關的狀態信息
mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
//mStatusFile指向/data/system/sync/pending.bin,該文件記錄了當前處于pending
//狀態的同步請求
mPendingFile = new AtomicFile(new File(syncDir,"pending.bin"));
//mStatusFile指向/data/system/sync/stats.bin,該文件記錄同步服務管理運行過程
//中的一些統計信息
mStatisticsFile = new AtomicFile(new File(syncDir,"stats.bin"));
/*
解析上述四個文件,從下面的代碼看,似乎是先讀(readXXX)后寫(writeXXX),這是怎么
回事?答案在于AtomicFile,它內部實際包含兩個文件,其中一個用于備份,防止數據丟失。
感興趣的讀者可以研究AtomicFile類,其實現非常簡單
*/
readAccountInfoLocked();
readStatusLocked();
readPendingOperationsLocked();
readStatisticsLocked();
readAndDeleteLegacyAccountInfoLocked();
writeAccountInfoLocked();
writeStatusLocked();
writePendingOperationsLocked();
writeStatisticsLocked();
}
~~~
上述init和SyncStorage的構造函數都比較簡單,故不再詳述。下面將討論一些有關accounts.xml的故事。以下是一個真實機器上的accounts.xml文件,如圖8-12所示。
:-: 
圖8-12 accounts.xml內容展示
圖8-12所示為筆者KindleFire(CM9的ROM)機器中accounts.xml文件的內容,其中兩個黑框中內容的作用如下:
- 第一個框中的listen-for-tickles,該標簽和Android平臺中的Master Sync有關。Master Sync用于控制手機中是否所有賬戶對應的所有數據項都自動同步。用戶可通過ContentResolver setMasterSyncAutomatically進行設置。
- 第二個框代表一個AuthorityInfo。AuthorityInfo記錄了賬戶和SyncService相關的一些信息。此框中的account為筆者的郵箱,type為“com.google”。另外,從圖8-12中還可發現,一個賬戶(包含account和type兩個屬性)可以對應多種類型的數據項,例如此框中對應的數據項是“com.android.email.provider”,而此框前面一個AuthorityInfo對應的數據項是“com.google.android.apps.books”。AuthorityInfo中的periodicSync用于控制周期同步的時間,單位是秒,默認是86400秒,也就是1天。另外,AuthorityInfo中還有一個重要屬性syncable,它的可選值為true、false或unknown(在代碼中,這3個值分別對應整型值1、0和-1)。
syncable的unknown狀態是個較難理解的概念,它和參數SYNC_EXTRAS_INITIALIZE有關,官方的解釋如下:
~~~
/**
Set by theSyncManager to request that the SyncAdapter initialize itself for
the givenaccount/authority pair. One required initialization step is to
ensure thatsetIsSyncable()has been called with a >= 0 value.
When thisflag is set the SyncAdapter does not need to do a full sync,
though itis allowed to do so.
*/
publicstatic final String SYNC_EXTRAS_INITIALIZE = "initialize";
~~~
由以上解釋可知,如果某個SyncService的狀態為unknown,那么在啟動它時必須傳遞一個SYNC_EXTRAS_INITIALIZE選項,SyncService解析該選項后即可知自己尚未被初始化。當它完成初始化后,需要調用setIsSyncable函數設置syncable的狀態為1。另外,SyncService初始化完成后,是否可接著執行同步請求呢?目前的設計是,它們并不會立即執行同步,需要用戶再次發起請求。讀者在后續小節中會看到與此相關的處理。
此處先來看setIsSyncable的使用示例,前面分析的EasAuthenticator addAccount中有如下的函數調用:
~~~
//添加完賬戶后,將設置對應的同步服務狀態為1
ContentResolver.setIsSyncable(account,EmailContent.AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account,EmailContent.AUTHORITY,
syncEmail);
~~~
在EasAuthenticator中,一旦添加了賬戶,就會設置對應SyncService的syncable狀態為1。SyncManager將根據這個狀態做一些處理,例如立即發起一次同步操作。
* * * * *
**注意**:是否設置syncable狀態和具體應用有關,圖8-12第二個框中的gmail郵件同步服務就沒有因為筆者添加了賬戶而設置syncable為1。
* * * * *
3. SyncAdaptersCache介紹
再看SyncAdaptersCache,其構造函數代碼如下:
**SyncAdaptersCache.java::SyncAdaptersCache**
~~~
SyncAdaptersCache(Context context) {
/*
調用基類RegisteredServicesCache的構造函數,其中SERVICE_INTERFACE和
和SERVICE_META_DATA的值為“android.content.SyncAdapter”,
ATTRIBUTES_NAME為字符串"sync-adapter"
*/
super(context, SERVICE_INTERFACE, SERVICE_META_DATA,
ATTRIBUTES_NAME, sSerializer);
}
~~~
SyncAdaptersCache的基類是RegisteredServicesCache。8.3.1節已經分析過RegisteredServicesCache了,此處不再贅述。下面展示一個實際的例子,如圖8-13所示。
:-: 
圖8-13 android.content.SyncAdapter.xml
圖8-13列出了筆者KindleFire上安裝的同步服務,其中黑框列出的是“om.android.exchange”,該項服務和Android中Exchange應用有關。Exchange的AndroidManifest.xml文件的信息如圖8-14所示。
:-: 
圖8-14 Exchange AndroidManifest.xml示意
圖8-14列出了Exchange應用所支持的針對郵件提供的同步服務,即EmailSyncAdapterService。該服務會通過meta-data中的resource來描述自己,這部分內容如圖8-15所示。
:-: 
圖8-15 syncadapter_email.xml內容展示
圖8-15告訴我們,EmailSyncAdapterService對應的賬戶類型是“com.android.exchange”,需要同步的郵件數據地址由contentAuthority表示,即本例中的“com.android.email.provider”。注意,EmailSyncAdapterService只支持從網絡服務端同步數據到本機,故supportsUploading為false。
再看SyncManager家族中最后一位成員SyncQueue。
4. SyncQueue介紹
SyncQueue用于管理同步操作對象SyncOperation。SyncQueue的構造函數代碼為:
**SyncQueue.java::SyncQueue**
~~~
public SyncQueue(SyncStorageEnginesyncStorageEngine,
finalSyncAdaptersCache syncAdapters) {
mSyncStorageEngine = syncStorageEngine;
//從SyncStorageEngine中取出上次沒有完成的同步操作信息,這類信息由
//PendingOperations表示
ArrayList<SyncStorageEngine.PendingOperation> ops
= mSyncStorageEngine.getPendingOperations();
final intN = ops.size();
for (inti=0; i<N; i++) {
SyncStorageEngine.PendingOperation op = ops.get(i);
//從SyncStorageEngine中取出該同步操作的backoff信息
finalPair<Long, Long> backoff =
syncStorageEngine.getBackoff(op.account,op.authority);
//從SyncAdaptersCache中取出該同步操作對應的同步服務信息,如果同步服務已經不存在,
//則無須執行后面的流程
finalRegisteredServicesCache.ServiceInfo<SyncAdapterType>
syncAdapterInfo= syncAdapters.getServiceInfo(
SyncAdapterType.newKey(op.authority,
op.account.type));
if (syncAdapterInfo == null) continue;
//構造一個SyncOperation對象
SyncOperation syncOperation = newSyncOperation(
op.account, op.syncSource, op.authority, op.extras, 0,
backoff != null ? backoff.first : 0,
syncStorageEngine.getDelayUntilTime(op.account, op.authority),
syncAdapterInfo.type.allowParallelSyncs());
syncOperation.expedited = op.expedited;
syncOperation.pendingOperation = op;
//將SyncOperation對象保存到mOperationsMap變量中
add(syncOperation, op);
}
}
~~~
SyncQueue比較簡單,其中一個比較難理解的概念是backoff,后文再對此作解釋。
至此,SyncManager及相關家族成員已介紹完畢。下面將通過實例分析同步服務的工作流程。在本例中,將同步Email數據,目標同步服務為EmailSyncAdapterService。
- 前言
- 第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 本章小結