本文共 4069 字,大约阅读时间需要 13 分钟。
Step 7. ActivityManagerService.getContentProviderImpl 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中: -
public final class ActivityManagerService extends ActivityManagerNative -
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { -
-
-
private final ContentProviderHolder getContentProviderImpl( -
IApplicationThread caller, String name) { -
ContentProviderRecord cpr; -
-
-
-
-
-
r = getRecordForAppLocked(caller); -
-
-
-
-
cpr = mProvidersByName.get(name); -
-
-
-
-
cpi = AppGlobals.getPackageManager(). -
resolveContentProvider(name, -
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); -
} catch (RemoteException ex) { -
-
-
-
-
cpr = mProvidersByClass.get(cpi.name); -
final boolean firstClass = cpr == null; -
-
-
-
AppGlobals.getPackageManager(). -
-
cpi.applicationInfo.packageName, -
-
-
cpr = new ContentProviderRecord(cpi, ai); -
} catch (RemoteException ex) { -
-
-
-
-
if (r != null && cpr.canRunHere(r)) { -
-
-
-
-
-
-
-
-
-
-
-
-
final int N = mLaunchingProviders.size(); -
-
-
if (mLaunchingProviders.get(i) == cpr) { -
-
-
-
-
-
-
-
final long origId = Binder.clearCallingIdentity(); -
ProcessRecord proc = startProcessLocked(cpi.processName, -
cpr.appInfo, false, 0, "content provider", -
new ComponentName(cpi.applicationInfo.packageName, -
-
-
mLaunchingProviders.add(cpr); -
-
-
-
-
-
-
mProvidersByClass.put(cpi.name, cpr); -
-
-
mProvidersByName.put(name, cpr); -
-
-
-
-
-
-
while (cpr.provider == null) { -
-
-
-
} catch (InterruptedException ex) { -
-
-
-
-
-
-
-
-
这个函数比较长,我们一步一步地分析。
函数首先是获取调用者的进程记录块信息: -
-
-
r = getRecordForAppLocked(caller); -
-
在我们这个情景中,要获取的就是应用程序Article的进程记录块信息了,后面会用到。 在ActivityManagerService中,有两个成员变量是用来保存系统中的Content Provider信息的,一个是mProvidersByName,一个是mProvidersByClass,前者是以Content Provider的authoriry值为键值来保存的,后者是以Content Provider的类名为键值来保存的。一个Content Provider可以有多个authority,而只有一个类来和它对应,因此,这里要用两个Map来保存,这里为了方便根据不同条件来快速查找而设计的。下面的代码就是用来检查要获取的Content Provider是否已经加存在的了: -
-
cpr = mProvidersByName.get(name); -
-
-
-
-
cpi = AppGlobals.getPackageManager(). -
resolveContentProvider(name, -
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); -
} catch (RemoteException ex) { -
-
-
-
-
cpr = mProvidersByClass.get(cpi.name); -
final boolean firstClass = cpr == null; -
-
-
-
AppGlobals.getPackageManager(). -
-
cpi.applicationInfo.packageName, -
-
-
cpr = new ContentProviderRecord(cpi, ai); -
} catch (RemoteException ex) { -
-
-
在我们这个情景中,由于是第一次调用ArticlesProvider接口,因此,在mProvidersByName和mProvidersByClass两个Map中都不存在ArticlesProvider的相关信息,因此,这里会通过AppGlobals.getPackageManager函数来获得PackageManagerService服务接口,然后分别通过它的resolveContentProvider和getApplicationInfo函数来分别获取ArticlesProvider应用程序的相关信息,分别保存在cpi和cpr这两个本地变量中。这些信息都是在安装应用程序的过程中保存下来的,具体可以参考 一文。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966983,如需转载请自行联系原作者