BatteryStatsService(為書寫方便,以后簡稱BSS)主要功能是收集系統中各模塊和應用進程用電量情況。抽象地說,BSS就是一塊電表,不過這塊電表不只是顯示總的耗電量,而是分門別類地顯示耗電量,力圖做到更為精準。
和其他服務不太一樣的是,BSS的創建和注冊是在ActivityManagerService中進行的,相關代碼如下:
**ActivityManagerService.java::ActivityManagerService構造函數**
~~~
private ActivityManagerService() {
......//創建BSS對象,傳遞一個File對象,指向/data/system/batterystats.bin
mBatteryStatsService= new BatteryStatsService(new File(
systemDir, "batterystats.bin").toString());
}
~~~
**ActivityManagerService.java::main**
~~~
//調用BSS的publish函數,在內部將其注冊到ServiceManager
m.mBatteryStatsService.publish(context);
~~~
下面來分析BSS的構造函數,見識一下這塊電表的樣子。
1. BatteryStatsService介紹
讓人大跌眼鏡的是,BSS其實只是一個殼,具體功能委托BatteryStatsImpl(以后簡稱BSImpl)來實現,代碼如下:
**BatteryStatsService.java::BatteryStatsService構造函數**
~~~
BatteryStatsService(String filename) {
mStats = new BatteryStatsImpl(filename);
}
~~~
圖5-2展示了BSS及BSImpl的家族圖譜。
:-: 
圖5-2 BSS及BSImpl家族圖譜
由圖5-2可知:
- BSS通過成員變量mStats指向一個BSImpl類型的對象。
- BSImpl從BatteryStats類派生。更重要的是,該類實現了Parcelable接口,由此可知,BSImpl對象的信息可以寫到Parcel包中,從而可通過Binder在進程間傳遞。實際上,在Android手機的設置中查到的用電信息就是來自BSImpl的。
BSS的getStatistics函數提供了查詢系統用電信息的接口,代碼如下:
~~~
public byte[] getStatistics() {
mContext.enforceCallingPermission(//檢查調用進程是否有BATTERY_STATS權限
android.Manifest.permission.BATTERY_STATS, null);
Parcel out= Parcel.obtain();
mStats.writeToParcel(out, 0);//將BSImpl信息寫到數據包中
byte[]data = out.marshall();//序列化為一個buffer,然后通過Binder傳遞
out.recycle();
returndata;
}
~~~
由此可以看出,電量統計的核心類是BSImpl,下面就來分析它。
2. 初識BSImpl
BSImpl功能是進行電量統計,那么是否存在計量工具呢?答案是肯定的,并且BSImpl使用了不止一種的計量工具。
(1) 計量工具和統計對象介紹
BSImpl一共使用了4種計量工具,如圖5-3所示。
:-: 
圖5-3 計量工具圖例
由圖5-3可知:
- 一共有兩大類計量工具,Counter用于計數,Timer用于計時。
- BSImpl實現了StopwatchTimer(即所謂的秒表)、SamplingTimer(抽樣計時)、Counter和SamplingCounter(抽樣計數)等4個具體的計量工具。
- BSImpl中定義了一個Unpluggable接口。當手機插上USB線充電(不論是由AC還是由USB供電)時,該接口的plug函數被調用。反之,當拔去USB線時,該接口的unplug函數被調用。設置這個接口的目的是為了滿足BSImpl對各種情況下系統用電量的統計要求。關于Unpluggable接口的作用,在后續內容中可以能見到。
雖然只有4種計量工具(筆者覺得已經相當多了),但是可以在很多地方使用它們。下面先來認識部分被掛牌要求統計用電量的對象,如表5-5所示。
:-: 
表5-5 用電量統計項
表5-5中的電量統計項已經夠多了吧?還不止這些,為了做到更精確,Android還希望能統計每個進程在各種情況下的耗電量。這是一項龐大的工程,怎么做到的呢?來看下一節的內容。
(2) BatteryStats.Uid介紹
在Android 4.0中,和進程相關的用電量統計并非以單個PID為劃分單元,而是以Uid為組,相關類結構如圖5-4所示。
:-: 
圖5-4 BatteryStats.Uid家族
由圖5-4可知:
- Wakelock用于統計該Uid對應進程使用wakeLock的情況。
- Proc用于統計Uid中某個進程的電量使用情況。
- Pkg用于統計某個特定Package的使用情況,其內部類Serv用于統計該Pkg中Service的用電情況。
- Sensor用于統計傳感器用電情況。
基于以上的了解,以后分析將會輕松很多,下面來分析它的代碼。
3. BSImpl流程分析
(1) 構造函數分析
先分析構造函數,代碼如下:
**BatteryStatsImpl.java::BatteryStatsImpl構造函數**
~~~
public BatteryStatsImpl(String filename) {
//JournaledFile為日志文件對象,內部包含兩個文件,原始文件和臨時文件。目的是雙備份,
//以防止在讀寫過程中文件信息丟失或出錯
mFile =new JournaledFile(new File(filename), new File(filename + ".tmp"));
mHandler= new MyHandler();//創建一個Handler對象
mStartCount++;
//創建表5-5中的用電統計項對象
mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
for (inti=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null,
mUnpluggables);
}
mInputEventCounter = new Counter(mUnpluggables);
......
mOnBattery= mOnBatteryInternal = false;//設置這兩位成員變量為false
initTimes();//①初始化統計時間
mTrackBatteryPastUptime = 0;
mTrackBatteryPastRealtime = 0;
mUptimeStart= mTrackBatteryUptimeStart =
SystemClock.uptimeMillis()* 1000;
mRealtimeStart= mTrackBatteryRealtimeStart =
SystemClock.elapsedRealtime()* 1000;
mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
mDischargeStartLevel = 0;
mDischargeUnplugLevel = 0;
mDischargeCurrentLevel = 0;
initDischarge(); //②初始化和電池level有關的成員變量
clearHistoryLocked();//③刪除用電統計的歷史記錄
}
~~~
要看懂這段代碼比較困難,主要原因是變量太多,并且沒有注釋說明。只能根據名字來推測了。在以上代碼中除了計量工具外,還出現了三大類變量:
- 用于統計時間的變量,例如mUptimeStart、mTrackBatteryPastUptime等。這些參數的初始化函數為initTimes。注意,系統時間分為uptime和realtime。uptime和realtime的時間起點都從系統啟動開始算(since the system was booted),但是uptime不包括系統休眠時間,而realtime包括系統休眠時間[^platform]。
- 用于記錄各種情況下電池電量的變量,如mDischargeStartLevel、mDischargeCurrentLevel等,這些成員變量的初始化函數為initDischarge。
- 用于保存歷史記錄的HistroryItem,在clearHistoryLocked函數中初始化,主要有mHistory、mHistoryEnd等成員變量(這些成員在clearHistoryLocked函數中出現)。
上述這些成員變量的具體作用,只有通過后文的分析才能弄清楚。這里先介紹StopwacherTimer。
~~~
//調用方式
mPhoneSignalScanningTimer = newStopwatchTimer(null, -200+1,
null,mUnpluggables);
//mUnpluggables類型為ArrayList<Unpluggable>,用于保存插拔USB線時需要對應更新用電
//信息的統計對象
// StopwatchTimer的構造函數
StopwatchTimer(Uid uid, int type,ArrayList<StopwatchTimer> timerPool,
ArrayList<Unpluggable>unpluggables) {
//在本例中,uid為0,type為負數,timerPool為空,unpluggables為mUnpluggables
super(type, unpluggables);
mUid =uid;
mTimerPool = timerPool;
}
// Timer的構造函數
Timer(int type, ArrayList<Unpluggable>unpluggables) {
mType =type;
mUnpluggables = unpluggables;
unpluggables.add(this);
}
~~~
在StopwatchTimer中比較難理解的就是unpluggables,根據注釋說明,當拔插USB線時,需要更新用電統計的對象,應該將其加入到mUnpluggables數組中。
在啟動秒表時,調用它的startRunningLocked函數,并傳入BSImpl實例,代碼如下:
~~~
void startRunningLocked(BatteryStatsImpl stats) {
if(mNesting++ == 0) {//嵌套調用控制
// getBatteryRealtimeLocked函數返回總的電池使用時間
mUpdateTime = stats.getBatteryRealtimeLocked(
SystemClock.elapsedRealtime()* 1000);
if (mTimerPool != null) {//不討論這種情況
}
mCount++;
mAcquireTime = mTotalTime;//計數控制,請讀者閱讀相關注釋說明
}
}
~~~
當停用秒表時,調用它的stopRunningLocked函數,代碼如下:
~~~
void stopRunningLocked(BatteryStatsImpl stats) {
if (mNesting == 0) {
return; //嵌套控制
}
if(--mNesting == 0) {
if(mTimerPool != null) {//不討論這種情況
}else {
final long realtime = SystemClock.elapsedRealtime() * 1000;
//計算此次啟動/停止周期的時間
final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
mNesting = 1;
//mTotalTime代表從啟動開始該秒停表一共記錄的時間
mTotalTime = computeRunTimeLocked(batteryRealtime);
mNesting = 0;
}
if (mTotalTime == mAcquireTime) mCount--;
}
}
~~~
在StopwatchTimer中定義了很多的時間參數,無非就是用于記錄各種時間,例如總耗時、最近一次工作周期的耗時等。如果不是工作需要(例如研究Settings應用中和BatteryInfo相關的內容),讀者僅需了解它的作用即可。
(2) ActivityManagerService和BSS交互
ActivityManagerService創建BSS后,還要進行幾項操作,具體代碼分別如下:
**ActivityManagerService.java::ActivityManagerService構造函數**
~~~
mBatteryStatsService = new BatteryStatsService(newFile(
systemDir, "batterystats.bin").toString());
//操作通過BSImpl創建的JournaledFile文件
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
//BSImpl的getIsOnBattery返回mOnBattery變量,初始化值為false
mOnBattery= DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
//設置回調,該回調也是用于信息統計,只能留到介紹ActivityManagerService時再來分析了
mBatteryStatsService.getActiveStatistics().setCallback(this);
~~~
**ActivityManagerService.java::main函數**
~~~
m.mBatteryStatsService.publish(context);
~~~
**BatteryStatsService.java::publish**
~~~
public void publish(Context context) {
mContext =context;
//注意,BSS服務叫做batteryinfo,而BatteryService服務叫做battery
ServiceManager.addService("batteryinfo", asBinder());
//PowerProfile見下文解釋
mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
//設置通信信號掃描超時時間
mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
com.android.internal.R.integer.config_radioScanningTimeout)
* 1000L);
}
~~~
在以上代碼中,比較有意思的是PowerProfile類,它將解析Android 4.0源碼/frameworks/base/core/res/res/xml/power_profile.xml文件。此XML文件存儲的是各種操作(和硬件相關)的耗電情況,如圖5-5所示。
:-: 
圖5-5 PowerProfile文件示例
由圖5-5可知,該文件保存了各種操作的耗電情況,以mAh(毫安)為單位。PowerProfile的getNumSpeedSteps將返回CPU支持的頻率值,目前在該XML中只定義了一個值,即400MHz。
注意在編譯時,各廠家會將特定硬件平臺的power_profile.xml復制到輸出目錄。此處展示的power_profile.xml和硬件平臺無關。
(3) BatteryService和BSS交互
BatteryService在它的processValues函數中和BSS交互,代碼如下:
**BatteryService.java**
~~~
private void processValues() {
......
mBatteryStats.setBatteryState(mBatteryStatus,mBatteryHealth, mPlugType,
mBatteryLevel, mBatteryTemperature,mBatteryVoltage);
}
~~~
BSS的工作由BSImpl來完成,所以直接setBatteryState函數的代碼:
**BatteryStatsImpl.java::setBatteryState**
~~~
public void setBatteryState(int status, inthealth, int plugType, int level,
int temp, int volt) {
synchronized(this) {
boolean onBattery = plugType == BATTERY_PLUGGED_NONE;//判斷是否為電池供電
intoldStatus = mHistoryCur.batteryStatus;
......
if(onBattery) {
//mDischargeCurrentLevel記錄當前使用電池供電時的電池電量
mDischargeCurrentLevel = level;
mRecordingHistory = true;//mRecordingHistory表示需要記錄一次歷史值
}
//此時,onBattery為當前狀態,mOnBattery為歷史狀態
if(onBattery != mOnBattery) {
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.batteryStatus = (byte)status;
mHistoryCur.batteryHealth = (byte)health;
......//更新mHistoryCur中的電池信息
setOnBatteryLocked(onBattery, oldStatus, level);
} else {
boolean changed = false;
if (mHistoryCur.batteryLevel != level) {
mHistoryCur.batteryLevel = (byte)level;
changed = true;
}
......//判斷電池信息是否發生變化
if (changed) {//如果發生變化,則需要增加一次歷史記錄
addHistoryRecordLocked(SystemClock.elapsedRealtime());
}
}
if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL){
mRecordingHistory = false;
}
}
}
~~~
setBatteryState函數的工作主要有兩項:
- 判斷當前供電狀態是否發生變化,由onBattery和mOnBattery進行比較。其中onBattery用于判斷當前是否為電池供電,mOnBattery為上次調用該函數時得到的判斷值。如果供電狀態發生變化(其實就是經歷一次USB拔插過程),則調用setOnBatteryLocked函數。
- 如果供電狀態未發生變化,則需要判斷電池信息是否發生變化,例如電量和電壓等。如果發生變化,則調用addHistoryRecordLocked。該函數用于記錄一次歷史信息。
接下來看setOnBatteryLocked函數的代碼:
**BatteryStatsImpl.java::setOnBatteryLocked**
~~~
void setOnBatteryLocked(boolean onBattery, intoldStatus, int level) {
boolean doWrite = false;
//發送一個消息給mHandler,將在內部調用ActivityManagerService設置的回調函數
Message m= mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
m.arg1 =onBattery ? 1 : 0;
mHandler.sendMessage(m);
mOnBattery = mOnBatteryInternal = onBattery;
longuptime = SystemClock.uptimeMillis() * 1000;
longmSecRealtime = SystemClock.elapsedRealtime();
longrealtime = mSecRealtime * 1000;
if(onBattery) {
//關于電量信息統計,有一個值得注意的地方:當oldStatus為滿電狀態,或當前電量
//大于90,或mDischargeCurrentLevel小于20并且當前電量大于80時,要清空統計
//信息,以開始新的統計。也就是說在滿足特定條件的情況下,電量使用統計信息會清零并重
//新開始。讀者不妨用自己手機一試
if(oldStatus == BatteryManager.BATTERY_STATUS_FULL || level >= 90
|| (mDischargeCurrentLevel < 20 && level >= 80)) {
doWrite = true;
resetAllStatsLocked();
mDischargeStartLevel = level;
}
//讀取/proc/wakelock文件,該文件反映了系統wakelock的使用狀態,
//感興趣的讀者可自行研究
updateKernelWakelocksLocked();
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
//添加一條歷史記錄
addHistoryRecordLocked(mSecRealtime);
//mTrackBatteryUptimeStart表示使用電池的開始時間,由uptime表示
mTrackBatteryUptimeStart = uptime;
// mTrackBatteryRealtimeStart表示使用電池的開始時間,由realtime表示
mTrackBatteryRealtimeStart = realtime;
//mUnpluggedBatteryUptime記錄總的電池使用時間(不論中間插拔多少次)
mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
// mUnpluggedBatteryRealtime記錄總的電池使用時間
mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
//記錄電量
mDischargeCurrentLevel =mDischargeUnplugLevel = level;
if(mScreenOn) {
mDischargeScreenOnUnplugLevel = level;
mDischargeScreenOffUnplugLevel = 0;
}else {
mDischargeScreenOnUnplugLevel = 0;
mDischargeScreenOffUnplugLevel = level;
}
mDischargeAmountScreenOn = 0;
mDischargeAmountScreenOff = 0;
//調用doUnplugLocked函數
doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
}else {
......//處理使用USB充電的情況,請讀者在上面討論的基礎上自行分析
}
......//記錄信息到文件
}
}
~~~
doUnplugLocked函數將更新對應信息,該函數比較簡單,無須贅述。另外,addHistoryRecordLocked函數用于增加一條歷史記錄(由HistoryItem表示),讀者也可自行研究。
從本節的分析可知,Android將電量統計分得非常細,例如由電池供電的情況需要統計,由USB/AC充電的情況也要統計,因此有setBatteryState函數的存在。
(4) PowerManagerService和BSS交互
PMS和BSS交互是最多的,此處以noteScreenOn和noteUserActivity為例,來介紹BSS到底是如何統計電量的。
先來看noteScreenOn函數。當開啟屏幕時,PMS會調用BSS的noteScreenOn以通知屏幕開啟,該函數在內部調用BSImpl的noteScreenOnLocked,其代碼如下:
**BatteryStatsImpl.java::noteScreenOnLocked**
~~~
public void noteScreenOnLocked() {
if(!mScreenOn) {
mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
//增加一條歷史記錄
addHistoryRecordLocked(SystemClock.elapsedRealtime());
mScreenOn = true;
//啟動mScreenOnTime秒停表,內部就是記錄時間,讀者可自行研究
mScreenOnTimer.startRunningLocked(this);
if(mScreenBrightnessBin >= 0)//啟動對應屏幕亮度的秒停表(參考表5-5)
mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
//屏幕開啟也和內核WakeLock有關,所以這里一樣要更新WakeLock的用電統計
noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
if(mOnBatteryInternal)
updateDischargeScreenLevelsLocked(false, true);
}
}
~~~
再來看noteUserActivity,當有輸入事件觸發PMS的userActivity時,該函數被調用,代碼如下,:
**BatteryStatsImpl.java::noteUserActivityLocked**
~~~
//BSS的noteUserActivity將調用BSImpl的noteUserActivityLocked
public void noteUserActivityLocked(int uid, intevent) {
getUidStatsLocked(uid).noteUserActivityLocked(event);
}
~~~
先是調用getUidStatsLocked以獲取一個Uid對象,如果該Uid是首次出現的,則要在內部創建一個Uid對象。直接來了解Uid的noteUserActivityLocked函數:
~~~
public void noteUserActivityLocked(int type) {
if(mUserActivityCounters == null) {
initUserActivityLocked();
}
if (type< 0) type = 0;
else if(type >= NUM_USER_ACTIVITY_TYPES)
type= NUM_USER_ACTIVITY_TYPES-1;
// noteUserActivityLocked只是調用對應type的Counter的stepAtomic函數
//每個Counter內部都有個計數器,stepAtomic使該計數器增1
mUserActivityCounters[type].stepAtomic();
}
~~~
mUserActivityCounters為一個7元Counter數組,該數組對應7種不同的輸入事件類型,在代碼中,由BSImpl的成員變量USER_ACTIVITY_TYPES表示,如下所示:
~~~
static final String[] USER_ACTIVITY_TYPES = {
"other", "cheek", "touch","long_touch", "touch_up", "button", "unknown"
};
~~~
另外,在LocalPowerManager中,也定義了相關的type值,如下所示:
**LocalPowerManager.java**
~~~
public interface LocalPowerManager {
publicstatic final int OTHER_EVENT = 0;
publicstatic final int BUTTON_EVENT = 1;
publicstatic final int TOUCH_EVENT = 2; //目前只使用這三種事件
......
}
~~~
[^platform]: 讀者可閱讀SDK文檔中關于SystemClock類的說明。
- 前言
- 第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 本章小結