Step 13. ActivityManagerService.attachApplicationLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
-
public final class ActivityManagerService extends ActivityManagerNative
-
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
-
......
-
-
private final boolean attachApplicationLocked(IApplicationThread thread,
-
int pid) {
-
// Find the application record that is being attached... either via
-
// the pid if we are running in multiple processes, or just pull the
-
// next app record if we are emulating process with anonymous threads.
-
ProcessRecord app;
-
if (pid != MY_PID && pid >= 0) {
-
synchronized (mPidsSelfLocked) {
-
app = mPidsSelfLocked.get(pid);
-
}
-
} else if (mStartingProcesses.size() > 0) {
-
......
-
} else {
-
......
-
}
-
-
......
-
-
app.thread = thread;
-
app.curAdj = app.setAdj = -100;
-
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
-
app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-
app.forcingToForeground = null;
-
app.foregroundServices = false;
-
app.debugging = false;
-
-
......
-
-
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
-
List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
-
-
try {
-
......
-
-
thread.bindApplication(processName, app.instrumentationInfo != null
-
? app.instrumentationInfo : app.info, providers,
-
app.instrumentationClass, app.instrumentationProfileFile,
-
app.instrumentationArguments, app.instrumentationWatcher, testMode,
-
isRestrictedBackupMode || !normalMode,
-
mConfiguration, getCommonServicesLocked());
-
-
......
-
} catch (Exception e) {
-
......
-
}
-
-
......
-
-
return true;
-
}
-
-
......
-
-
private final List generateApplicationProvidersLocked(ProcessRecord app) {
-
List providers = null;
-
try {
-
providers = AppGlobals.getPackageManager().
-
queryContentProviders(app.processName, app.info.uid,
-
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
-
} catch (RemoteException ex) {
-
}
-
if (providers != null) {
-
final int N = providers.size();
-
for (int i=0; i<N; i++) {
-
ProviderInfo cpi =
-
(ProviderInfo)providers.get(i);
-
ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
-
if (cpr == null) {
-
cpr = new ContentProviderRecord(cpi, app.info);
-
mProvidersByClass.put(cpi.name, cpr);
-
}
-
app.pubProviders.put(cpi.name, cpr);
-
app.addPackage(cpi.applicationInfo.packageName);
-
ensurePackageDexOpt(cpi.applicationInfo.packageName);
-
}
-
}
-
return providers;
-
}
-
-
......
-
}
这个函数首先是根据传进来的进程ID找到相应的进程记录块,注意,这个进程ID是应用程序ArticlesProvider的ID,然后对这个进程记录块做一些初倾始化的工作。再接下来通过调用generateApplicationProvidersLocked获得需要在这个过程中加载的Content Provider列表,在我们这个情景中,就只有ArticlesProvider这个Content Provider了。最后调用从参数传进来的IApplicationThread对象thread的bindApplication函数来执行一些应用程序初始化工作。从Android应用程序启动过程源代码分析一文中我们知道,在Android系统中,每一个应用程序进程都加载了一个ActivityThread实例,在这个ActivityThread实例里面,有一个成员变量mAppThread,它是一个Binder对象,类型为ApplicationThread,实现了IApplicationThread接口,它是专门用来和ActivityManagerService服务进行通信的。因此,调用下面语句:
-
thread.bindApplication(processName, app.instrumentationInfo != null
-
? app.instrumentationInfo : app.info, providers,
-
app.instrumentationClass, app.instrumentationProfileFile,
-
app.instrumentationArguments, app.instrumentationWatcher, testMode,
-
isRestrictedBackupMode || !normalMode,
-
mConfiguration, getCommonServicesLocked());
就会进入到应用程序ArticlesProvider进程中的ApplicationThread对象的bindApplication函数中去。在我们这个情景场,这个函数调用中最重要的参数便是第三个参数providers了,它是我们要处理的对象。
Step 14. ApplicationThread.bindApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
-
public final class ActivityThread {
-
......
-
-
private final class ApplicationThread extends ApplicationThreadNative {
-
......
-
-
public final void bindApplication(String processName,
-
ApplicationInfo appInfo, List<ProviderInfo> providers,
-
ComponentName instrumentationName, String profileFile,
-
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
-
int debugMode, boolean isRestrictedBackupMode, Configuration config,
-
Map<String, IBinder> services) {
-
if (services != null) {
-
// Setup the service cache in the ServiceManager
-
ServiceManager.initServiceCache(services);
-
}
-
-
AppBindData data = new AppBindData();
-
data.processName = processName;
-
data.appInfo = appInfo;
-
data.providers = providers;
-
data.instrumentationName = instrumentationName;
-
data.profileFile = profileFile;
-
data.instrumentationArgs = instrumentationArgs;
-
data.instrumentationWatcher = instrumentationWatcher;
-
data.debugMode = debugMode;
-
data.restrictedBackupMode = isRestrictedBackupMode;
-
data.config = config;
-
queueOrSendMessage(H.BIND_APPLICATION, data);
-
}
-
-
......
-
}
-
-
......
-
}
这个函数把相关的信息都封装成一个AppBindData对象,然后以一个消息的形式发送到主线程的消息队列中去等等待处理。这个消息最终是是在ActivityThread类的handleBindApplication函数中进行处理的。
Step 15. ActivityThread.handleBindApplication
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
-
public final class ActivityThread {
-
......
-
-
private final void handleBindApplication(AppBindData data) {
-
......
-
-
List<ProviderInfo> providers = data.providers;
-
if (providers != null) {
-
installContentProviders(app, providers);
-
......
-
}
-
-
......
-
}
-
-
......
-
}
这个函数的内容比较多,我们忽略了其它无关的部分,只关注和Content Provider有关的逻辑,这里主要就是调用installContentProviders函数来在本地安装Content Providers信息。
Step 16. ActivityThread.installContentProviders
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
-
public final class ActivityThread {
-
......
-
-
private final void installContentProviders(
-
Context context, List<ProviderInfo> providers) {
-
final ArrayList<IActivityManager.ContentProviderHolder> results =
-
new ArrayList<IActivityManager.ContentProviderHolder>();
-
-
Iterator<ProviderInfo> i = providers.iterator();
-
while (i.hasNext()) {
-
ProviderInfo cpi = i.next();
-
StringBuilder buf = new StringBuilder(128);
-
buf.append("Pub ");
-
buf.append(cpi.authority);
-
buf.append(": ");
-
buf.append(cpi.name);
-
Log.i(TAG, buf.toString());
-
IContentProvider cp = installProvider(context, null, cpi, false);
-
if (cp != null) {
-
IActivityManager.ContentProviderHolder cph =
-
new IActivityManager.ContentProviderHolder(cpi);
-
cph.provider = cp;
-
results.add(cph);
-
// Don't ever unload this provider from the process.
-
synchronized(mProviderMap) {
-
mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
-
}
-
}
-
}
-
-
try {
-
ActivityManagerNative.getDefault().publishContentProviders(
-
getApplicationThread(), results);
-
} catch (RemoteException ex) {
-
}
-
}
-
-
......
-
}
这个函数主要是做了两件事情,一是调用installProvider来在本地安装每一个Content Proivder的信息,并且为每一个Content Provider创建一个ContentProviderHolder对象来保存相关的信息。ContentProviderHolder对象是一个Binder对象,是用来把Content Provider的信息传递给ActivityManagerService服务的。当这些Content Provider都处理好了以后,还要调用ActivityManagerService服务的publishContentProviders函数来通知ActivityManagerService服务,这个进程中所要加载的Content Provider,都已经准备完毕了,而ActivityManagerService服务的publishContentProviders函数的作用就是用来唤醒在前面Step 7等待的线程的了。我们先来看installProvider的实现,然后再来看ActivityManagerService服务的publishContentProviders函数的实现。
本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966988,如需转载请自行联系原作者