2.1 AMS获取ContentProvider
AMS中的ContentProvider方法调用流程图如下,
AMS的getContentProviderImpl主要逻辑如下,
1,安全检查
if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))!= null) {
throw new SecurityException(msg);
}
2,调用PMS的resolveContentProvider方法匹配出目标ContentProvider注册的ContentProvider,这个匹配过程
和其他三大组件完全类似。
try {
checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
cpi = AppGlobals.getPackageManager().resolveContentProvider(name,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
} catch (RemoteException ex) {
}
3,如果目标ContentProvider的进程已经创建了,就调用目标ContentProvider的ActivityThread的scheduleInstallProvider
方法安装ContentProvider,
try {
proc.thread.scheduleInstallProvider(cpi);
} catch (RemoteException e) {
}
4,如果目标ContentProvider的进程还未创建,就调用startProcessLocked方法创建进程,
proc = startProcessLocked(cpi.processName, cpr.appInfo, false, 0, "content provider",
new ComponentName(cpi.applicationInfo.packageName, cpi.name), false, false, false);
创建进程在此就不论述了,在创建进程的过程中会安装ContentProvider。
5,等待目标ContentProvider的安装,
synchronized (cpr) {
while (cpr.provider == null) {
if (cpr.launchingApp == null) {
Slog.w(TAG, "Unable to launch app "
+ cpi.applicationInfo.packageName + "/"
+ cpi.applicationInfo.uid + " for provider "
+ name + ": launching app became null");
EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
UserHandle.getUserId(cpi.applicationInfo.uid),
cpi.applicationInfo.packageName,
cpi.applicationInfo.uid, name);
return null;
}
try {
if (DEBUG_MU) Slog.v(TAG_MU,
"Waiting to start provider " + cpr
+ " launchingApp