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的家族图谱。
:-: ![](http://img.blog.csdn.net/20150803122147777?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图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所示。
:-: ![](http://img.blog.csdn.net/20150803122205478?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图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所示。
:-: ![ 用电量统计项](https://box.kancloud.cn/29c4adc2bf3a5e42dd6b8d3ffb0a24de_792x344.png =792x344)
表5-5 用电量统计项
表5-5中的电量统计项已经够多了吧?还不止这些,为了做到更精确,Android还希望能统计每个进程在各种情况下的耗电量。这是一项庞大的工程,怎么做到的呢?来看下一节的内容。
(2) BatteryStats.Uid介绍
在Android 4.0中,和进程相关的用电量统计并非以单个PID为划分单元,而是以Uid为组,相关类结构如图5-4所示。
:-: ![](http://img.blog.csdn.net/20150803122221423?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图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所示。
:-: ![](http://img.blog.csdn.net/20150803122238418?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图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 本章小结