startActivityAndWait函数有很多参数,先来认识一下它们。
**ActiivtyManagerService.java::startActivityAndWait原型**
~~~
publicfinal WaitResult startActivityAndWait(
/*
在绝大多数情况下,一个Acitivity的启动是由一个应用进程发起的,IApplicationThread是
应用进程和AMS交互的通道,也可算是调用进程的标示,在本例中,AM并非一个应用进程,所以
传递的caller为null
*/
IApplicationThread caller,
//Intent及resolvedType,在本例中,resolvedType为null
Intentintent, String resolvedType,
//下面两个参数和授权有关,读者可参考第3章对CopyboardService分析中介绍的授权知识
Uri[] grantedUriPermissions,//在本例中为null
intgrantedMode,//在本例中为0
IBinder resultTo,//在本例中为null,用于接收startActivityForResult的结果
StringresultWho,//在本例中为null
//在本例中为0,该值的具体意义由调用者解释。如果该值大于等于0,则AMS内部保存该值,
//并通过onActivityResult返回给调用者
int requestCode,
boolean onlyIfNeeded,//本例为false
boolean debug,//是否调试目标进程
//下面3个参数和性能统计有关
StringprofileFile,
ParcelFileDescriptor profileFd, booleanautoStopProfiler)
~~~
关于以上代码中一些参数的具体作用,以后碰到时会再作分析。建议读者先阅读SDK文档中关于Activity类定义的几个函数,如startActivity、startActivityForResult及onActivityResult等。
startActivityAndWait的代码如下:
**ActivityManagerService.java::startActivityAndWait**
~~~
publicfinal WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, Uri[]grantedUriPermissions,
int grantedMode, IBinder resultTo,StringresultWho, int requestCode,
booleanonlyIfNeeded, boolean debug,String profileFile,
ParcelFileDescriptor profileFd, booleanautoStopProfiler) {
//创建WaitResult对象用于存储处理结果
WaitResult res = new WaitResult();
//mMainStack为ActivityStack类型,调用它的startActivityMayWait函数
mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, profileFile, profileFd,
autoStopProfiler, res, null);//最后一个参数为Configuration,
//在本例中为null
returnres;
}
~~~
mMainStack为AMS的成员变量,类型为ActivityStack,该类是Activity调度的核心角色。正式分析它之前,有必要先介绍一下相关的基础知识。
1. Task、Back Stack、ActivityStack及Launch mode
(1) 关于Task及Back Stack的介绍
先来看图6-10。
:-: ![](http://img.blog.csdn.net/20150803122911609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6-10 用户想干什么
图6-10列出了用户在Android系统上想干的三件事情,分别用A、B、C表示,将每一件事情称为一个Task。一个Task还可细分为多个子步骤,即Activity。
* * * * *
**提示**:为什么叫Activity?读者可参考Merrian-Webster词典对Activity的解释[^①]:“an organizational unit forperforming a specific function”,也就是说,它是一个有组织的单元,用于完成某项指定功能。
* * * * *
由图6-10可知,A、B两个Task使用了不同的Activity来完成相应的任务。注意,A、B这两个Task的Activity之间没有复用。
再来看C这个Task,它可细分为4个Activity,其中有两个Activity分别使用了A Task的A1、B Task的B2。C Task为什么不新建自己的Activity,反而要用其他Task的呢?这是因为用户想做的事情(即Task)可以完全不同,但是当细分Task为Activity时,就可能出现Activity功能类似的情况。既然A1、B2已能满足要求,为何还要重复“发明轮子”呢?另外,通过重用Activity,也可为用户提供一致的界面和体验。
了解Android设计理念后,我们来看看Android是如何组织Task及它所包含的Activity的。此处有一个简单的例子,如图6-11所示。
:-: ![](http://img.blog.csdn.net/20150803122942720?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6-11 Task及Back Stack示例
由图6-11可知:
- 本例中的Task包含4个Activity。用户可单击按钮跳转到下一个Activity。同时,通过返回键可回到上一个Activity。
- 虚线下方是这些Activity的组织方式。Android采用了Stack的方法管理这3个Activity。例如在A1启动A2后,A2入栈成为栈顶成员,A1成为栈底成员,而界面显示的是栈顶成员的内容。当按返回键时,A3出栈,这时候A2成为栈顶,界面显示也相应变成了A2。
以上是一个Task的情况。那么,多个Task又会是何种情况呢?如图6-12所示。
:-: ![](http://img.blog.csdn.net/20150803123111793?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6-12 多个Task的情况
由图6-12可知:对多Task的情况来说,系统只支持一个处于前台的Task,即用户当前看到的Activity所属的Task,其余的Task均处于后台,这些后台Task内部的Activity保持顺序不变。用户可以一次将整个Task挪到后台或者置为前台。
* * * * *
**提示**:用过Android手机的读者应该知道,长按Home键,系统会弹出近期Task列表,使用户能快速在多个Task间切换。
* * * * *
以上内容从抽象角度介绍了什么是Task,以及Android如何分解Task和管理Activity,那么在实际代码中,是如何考虑并设计的呢?
(2) 关于ActivityStack的介绍
通过上述分析,我们对Android的设计有了一定了解,那么如何用代码来实现这一设计呢?此处有两点需要考虑:
- Task内部Activity的组织方式。由图6-11可知,Android通过先入后出的方式来组织Activity。数据结构中的Stack即以这种方式工作。
- 多个Task的组织及管理方式。
Android设计了一个ActivityStack类来负责上述工作,它的组成如图6-13所示。
:-: ![](http://img.blog.csdn.net/20150803123156782?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图6-13 ActivityStack及相关成员
由图6-13可知:
- Activity由ActivityRecord表示,Task由TaskRecord表示。ActivityRecord的task成员指向该Activity所在的Task。state变量用于表示该Activity所处的状态(包括INITIALIZING、RESUMED、PAUSED等状态)。
- ActivityStack用mHistory这个ArrayList保存ActivityRecord。令人大跌眼镜的是,该mHistory保存了系统中所有Task的ActivityRecord,而不是针对某个Task进行保存。
- ActivityStack的mMainStack成员比较有意思,它代表此ActivityStack是否为主ActivityStack。有主必然有从,但是目前系统中只有一个ActivityStack,并且它的mMainStack为true。从ActivityStack的命名可推测,Android在开发之初也想用ActivityStack来管理单个Task中的ActivityRecord(在ActivityStack.java的注释中说过,该类为“State and management of asingle stack of activities”),但不知何故,在现在的代码实现将所有Task的ActivityRecord都放到mHistory中了,并且依然保留mMainStack。
- ActivityStack中没有成员用于保存TaskRecord。
由上述内容可知,ActivityStack采用数组的方式保存所有Task的ActivityRecord,并且没有成员保存TaskRecord。这种实现方式有优点亦有缺点:
- 优点是少了TaskRecord一级的管理,直接以ActivityRecord为管理单元。这种做法能降低管理方面的开销。
- 缺点是弱化了Task的概念,结构不够清晰。
下面来看ActivityStack中几个常用的搜索ActivityRecord的函数,代码如下:
**ActivityStack.java::topRunningActivityLocked**
~~~
/* topRunningActivityLocked:
找到栈中第一个与notTop不同的,并且不处于finishing状态的ActivityRecord。当notTop为
null时,该函数即返回栈中第一个需要显示的ActivityRecord。提醒读者,栈的出入口只能是栈顶。
虽然mHistory是一个数组,但是查找均从数组末端开始,所以其行为也粗略符合Stack的定义
*/
final ActivityRecordtopRunningActivityLocked(ActivityRecord notTop) {
int i =mHistory.size()-1;
while (i>= 0) {
ActivityRecord r = mHistory.get(i);
if (!r.finishing && r != notTop) return r;
i--;
}
returnnull;
}
~~~
类似的函数还有:
**ActivityStack.java::topRunningNonDelayedActivityLocked**
~~~
/* topRunningNonDelayedActivityLocked
与topRunningActivityLocked类似,但ActivityRecord要求增加一项,即delayeResume为
false
*/
final ActivityRecordtopRunningNonDelayedActivityLocked(ActivityRecord notTop) {
int i =mHistory.size()-1;
while(i >= 0) {
ActivityRecord r = mHistory.get(i);
//delayedResume变量控制是否暂缓resume Activity
if (!r.finishing && !r.delayedResume&& r != notTop) return r;
i--;
}
returnnull;
}
~~~
ActivityStack还提供findActivityLocked函数以根据Intent及ActivityInfo来查找匹配的ActivityRecord,同样,查找也是从mHistory尾端开始,相关代码如下:
**ActivityStack.java::findActivityLocked**
~~~
private ActivityRecord findActivityLocked(Intentintent, ActivityInfo info) {
ComponentName cls = intent.getComponent();
if(info.targetActivity != null)
cls= new ComponentName(info.packageName, info.targetActivity);
final intN = mHistory.size();
for (inti=(N-1); i>=0; i--) {
ActivityRecord r = mHistory.get(i);
if (!r.finishing)
if (r.intent.getComponent().equals(cls))return r;
}
return null;
}
~~~
另一个findTaskLocked函数的返回值是ActivityRecord,其代码如下:
**ActivityStack.java::findTaskLocked**
~~~
private ActivityRecord findTaskLocked(Intentintent, ActivityInfo info) {
ComponentName cls = intent.getComponent();
if(info.targetActivity != null)
cls= new ComponentName(info.packageName, info.targetActivity);
TaskRecord cp = null;
final intN = mHistory.size();
for (inti=(N-1); i>=0; i--) {
ActivityRecord r = mHistory.get(i);
//r.task!=cp,表示不搜索属于同一个Task的ActivityRecord
if(!r.finishing && r.task != cp
&& r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
cp = r.task;
//如果Task的affinity相同,则返回这条ActivityRecord
if(r.task.affinity != null) {
if(r.task.affinity.equals(info.taskAffinity)) return r;
}else if (r.task.intent != null
&&r.task.intent.getComponent().equals(cls)) {
//如果Task Intent的ComponentName相同
return r;
}else if (r.task.affinityIntent != null
&&r.task.affinityIntent.getComponent().equals(cls)) {
//Task affinityIntent考虑
return r;
}//if (r.task.affinity != null)判断结束
}//if(!r.finishing && r.task != cp......)判断结束
}//for循环结束
returnnull;
}
~~~
其实,findTaskLocked是根据mHistory中ActivityRecord所属的Task的情况来进行相应的查找工作。
以上这4个函数均是ActivityStack中常用的函数,如果不需要逐项(case by case)地研究AMS,那么读者仅需了解这几个函数的作用即可。
(3) 关于Launch Mode的介绍
Launch Mode用于描述Activity的启动模式,目前一共有4种模式,分别是standard、singleTop、singleTask和singleInstance。初看它们,较难理解,实际上不过是Android玩的一个“小把戏“而已。启动模式就是用于控制Activity和Task关系的。
- standard:一个Task中可以有多个相同类型的Activity。注意,此处是相同类型的Activity,而不是同一个Activity对象。例如在Task中有A、B、C、D4个Activity,如果再启动A类Activity, Task就会变成A、B、C、D、A。最后一个A和第一个A是同一类型,却并非同一对象。另外,多个Task中也可以有同类型的Activity。
- singleTop:当某Task中有A、B、C、D4个Activity时,如果D想再启动一个D类型的Activity,那么Task将是什么样子呢?在singleTop模式下,Task中仍然是A、B、C、D,只不过D的onNewIntent函数将被调用以处理这个新Intent,而在standard模式下,则Task将变成A、B、C、D、D,最后的D为新创建的D类型Activity对象。在singleTop这种模式下,只有目标Acitivity当前正好在栈顶时才有效,例如只有处于栈顶的D启动时才有用,如果D启动不处于栈顶的A、B、C等,则无效。
- singleTask:在这种启动模式下,该Activity只存在一个实例,并且将和一个Task绑定。当需要此Activity时,系统会以onNewIntent方式启动它,而不会新建Task和Activity。注意,该Activity虽只有一个实例,但是在Task中除了它之外,还可以有其他的Activity。
- singleInstance:它是singleTask的加强版,即一个Task只能有这么一个设置了singleInstance的Activity,不能再有别的Activity。而在singleTask模式中,Task还可以有其他的Activity。
* * * * *
**注意**,Android建议一般的应用开发者不要轻易使用最后两种启动模式。因为这些模式虽然名意上为Launch Mode,但是它们也会影响Activity出栈的顺序,导致用户按返回键返回时导致不一致的用户体验。
* * * * *
除了启动模式外,Android还有其他一些标志用于控制Activity及Task之间的关系。这里只列举一二,详细信息请参阅SDK文档中Intent的相关说明。
- FLAG_ACTIVITY_NEW_TASK:将目标Activity放到一个新的Task中。
- FLAG_ACTIVITY_CLEAR_TASK:当启动一个Activity时,先把和目标Activity有关联的Task“干掉“,然后启动一个新的Task,并把目标Activity放到新的Task中。该标志必须和FLAG_ACTIVITY_NEW_TASK标志一起使用。
- FLAG_ACTIVITY_CLEAR_TOP:当启动一个不处于栈顶的Activity时候,先把排在它前面的Activity“干掉”。例如Task有A、B、C、D4个Activity,要要启动B,直接把C、D“干掉”,而不是新建一个B。
* * * * *
**提示**:这些启动模式和标志,在笔者看来很像洗扑克牌时的手法,因此可以称之为小把戏。虽是小把戏,但是相关代码的逻辑及分支却异常繁杂,我们应从更高的角度来看待它们。
* * * * *
介绍完上面的知识后,下面来分析ActivityStack的startActivityMayWait函数。
2. ActivityStack的startActivityMayWait函数分析
startActivityMayWait函数的目标是启动com.dfp.test.TestActivity,假设系统之前没有启动过该Activity,本例最终的结果将是:
- 由于在am中设置了FLAG_ACTIVITY_NEW_TASK标志,因此除了会创建一个新的ActivityRecord外,还会新创建一个TaskRecord。
- 还需要启动一个新的应用进程以加载并运行com.dfp.test.TestActivity的一个实例。
- 如果TestActivity不是Home,还需要停止当前正在显示的Activity。
好了,将这个函数分三部分进行介绍,先来分析第一部分。
(1) startActivityMayWait分析之一
**ActivityStack.java::startActivityMayWait**
~~~
final int startActivityMayWait(IApplicationThreadcaller, int callingUid,
Intentintent, String resolvedType, Uri[] grantedUriPermissions,
intgrantedMode, IBinder resultTo,
StringresultWho, int requestCode, boolean onlyIfNeeded,
booleandebug, String profileFile, ParcelFileDescriptor profileFd,
booleanautoStopProfiler, WaitResult outResult, Configuration config) {
......
//在本例中,已经指明了Component,这样可省去为Intent匹配搜索之苦
booleancomponentSpecified = intent.getComponent() != null;
//创建一个新的Intent,防止客户传入的Intent被修改
intent =new Intent(intent);
//查询满足条件的ActivityInfo,在resolveActivity内部和PKMS交互,读者不妨自己
//尝试分析该函数
ActivityInfoaInfo = resolveActivity(intent, resolvedType, debug,
profileFile, profileFd,autoStopProfiler);
synchronized(mService) {
int callingPid;
if (callingUid >= 0) {
callingPid= -1;
} else if (caller == null) {//本例中,caller为null
callingPid= Binder.getCallingPid();//取出调用进程的Pid
//取出调用进程的Uid。在本例中,调用进程是am,它由shell启动
callingUid= Binder.getCallingUid();
} else {
callingPid= callingUid = -1;
}// if (callingUid >= 0)判断结束
//在本例中config为null
mConfigWillChange= config != null
&& mService.mConfiguration.diff(config) != 0;
finallong origId = Binder.clearCallingIdentity();
if (mMainStack && aInfo != null&& (aInfo.applicationInfo.flags&
ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0){
/*
AndroidManifest.xml中的Application标签可以声明一个cantSaveState
属性,设置了该属性的Application将不享受系统提供的状态保存/恢复功能。
当一个Application退到后台时,系统会为它保存状态,当调度其到前台运行时, 将恢复它之前的状态,以保证用户体验的连续性。声明了该属性的Application被称为
“heavy weight process”。可惜系统目前不支持该属性,因为PackageParser
将不解析该属性。详情请见PackageParser.java parseApplication函数
*/
}
......//待续
~~~
startActivityMayWait第一阶段的工作内容相对较简单:
- 首先需要通过PKMS查找匹配该Intent的ActivityInfo。
- 处理FLAG_CANT_SAVE_STATE的情况,但系统目前不支持此情况。
- 另外,获取调用者的pid和uid。由于本例的caller为null,故所得到的pid和uid均为am所在进程的uid和pid。
下面介绍startActivityMayWait第二阶段的工作。
(2) startActivityMayWait分析之二
**ActivityStack.java::startActivityMayWait**
~~~
//调用此函数启动Activity,将返回值保存到res
int res = startActivityLocked(caller, intent,resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, callingPid, callingUid,
onlyIfNeeded, componentSpecified, null);
//如果configuration发生变化,则调用AMS的updateConfigurationLocked
//进行处理。关于这部分内容,读者学完本章后可自行分析
if(mConfigWillChange && mMainStack) {
mService.enforceCallingPermission(
android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
mConfigWillChange= false;
mService.updateConfigurationLocked(config,null, false);
}
~~~
此处,启动Activity的核心函数是startActivityLocked,该函数异常复杂,将用一节专门分析。下面先继续分析startActivityMayWait第三阶段的工作。
(3) startActivityMayWait分析之三
**ActivityStack.java::startActivityMayWait**
~~~
if(outResult != null) {
outResult.result = res;//设置启动结果
if(res == IActivityManager.START_SUCCESS) {
//将该结果加到mWaitingActivityLaunched中保存
mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();//等待启动结果
}
} while (!outResult.timeout && outResult.who == null);
}else if (res == IActivityManager.START_TASK_TO_FRONT) {
......//处理START_TASK_TO_FRONT结果,读者可自行分析
}
}//if(outResult!= null)结束
return res;
}
}
~~~
第三阶段的工作就是根据返回值做一些处理,那么res返回成功(即res== IActivityManager.START_SUCCESS的时候)后为何还需要等待呢?
这是因为目标Activity要运行在一个新的应用进程中,就必须等待那个应用进程正常启动并处理相关请求。注意,只有am设置了-W选项,才会进入wait这一状态。
[^①]:http://www.merriam-webster.com/dictionary/activity中第六条解释。
- 前言
- 第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 本章小结