ContentProvider是Android系统的四大组件之一,主要用于向外部提供数据。不仅可以向自己应用进程提供数据,也可以向其他进程的提供数据。所以在分析ContentProvider的时候我们首先分析本进程的ContentProvider的启动过程,然后再分析调用其他进程的ContentProvider的时候ContentProvider的安装启动过程。
本进程ContentProvider启动过程分析
本进程内的ContentProvider一般是在进程启动的时候就启动并创建的。在Activity的启动过程中分析过新进程的启动过程。
1. 创建一个新的进程。调用ActivityThread的main方法
2. 调用ActivityThread的attach方法
3. 调用ActivityManagerService的attachApplication方法,通知新的进程创建完成,根据新创建的进程初始化ProcessRecord的信息。然后查询所有和本进程相关的ContentProvider信息。
4. 调用新建进程的bindApplication方法,通知新进程安装并启动这些ContentProvider
以上就是本进程的ContentProvider的启动和安装过程。第一第二步我们不再分析,直接从AMS服务的attachApplication方法开始分析。
1. AMS.attachApplication
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
//找到之前创建的ProcessRecord对象,之前的ProcessRecord对象还没有指向任何一个进程
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//根据创建的进程来初始化这个ProcessRecord对象,使它指向新创建的进程
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
//使用generateApplicationProvidersLocked方法在PMS服务中查询所有和该进程有关的ContentProvider信息
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
……
//最终调用新建进程的bindApplication来创建并启动该ContentProvider
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
……
}
在该方法中调用了generateApplicationProvidersLocked方法来查询和新建进程相关的ContetProvider的信息,保存在Providers列表中。同时在该方法中,还将查询到的每一个ContentProvider的信息,封装成了一个ContentProviderRecord对象,保存了ProviderMap中。
随后调用新建进程的binderApplication方法的时候将providers信息作为参数传入了新建进程。
2. ApplicationThread.bindApplication
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
……
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
ApplicationThread接收到AMS服务发送的请求,然后通过Handler发送BIND_APPLICATION消息给Handler来处理。Handler的handlerMessage接收到BIND_APPLICATION