Android应用程序组件Content Provider的启动过程源代码分析(3)
16lz
2021-01-23
Step 7.ActivityManagerService.getContentProviderImpl 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
函数首先是获取调用者的进程记录块信息:
这个函数比较长,我们一步一步地分析。
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalContentProviderHoldergetContentProviderImpl(
- IApplicationThreadcaller,Stringname){
- ContentProviderRecordcpr;
- ProviderInfocpi=null;
- synchronized(this){
- ProcessRecordr=null;
- if(caller!=null){
- r=getRecordForAppLocked(caller);
- ......
- }
- //Firstcheckifthiscontentproviderhasbeenpublished...
- cpr=mProvidersByName.get(name);
- if(cpr!=null){
- ......
- }else{
- try{
- cpi=AppGlobals.getPackageManager().
- resolveContentProvider(name,
- STOCK_PM_FLAGS|PackageManager.GET_URI_PERMISSION_PATTERNS);
- }catch(RemoteExceptionex){
- }
- ......
- }
- cpr=mProvidersByClass.get(cpi.name);
- finalbooleanfirstClass=cpr==null;
- if(firstClass){
- try{
- ApplicationInfoai=
- AppGlobals.getPackageManager().
- getApplicationInfo(
- cpi.applicationInfo.packageName,
- STOCK_PM_FLAGS);
- ......
- cpr=newContentProviderRecord(cpi,ai);
- }catch(RemoteExceptionex){
- //pmisinsameprocess,thiswillneverhappen.
- }
- }
- if(r!=null&&cpr.canRunHere(r)){
- //Ifthisisamultiprocessprovider,thenjustreturnits
- //infoandallowthecallertoinstantiateit.Onlydo
- //thisiftheprovideristhesameuserasthecaller's
- //process,orcanrunasroot(socanbeinanyprocess).
- returncpr;
- }
- ......
- //Thisissingleprocess,andourappisnowconnectingtoit.
- //Seeifwearealreadyintheprocessoflaunchingthis
- //provider.
- finalintN=mLaunchingProviders.size();
- inti;
- for(i=0;i<N;i++){
- if(mLaunchingProviders.get(i)==cpr){
- break;
- }
- }
- //Iftheproviderisnotalreadybeinglaunched,thengetit
- //started.
- if(i>=N){
- finallongorigId=Binder.clearCallingIdentity();
- ProcessRecordproc=startProcessLocked(cpi.processName,
- cpr.appInfo,false,0,"contentprovider",
- newComponentName(cpi.applicationInfo.packageName,
- cpi.name),false);
- ......
- mLaunchingProviders.add(cpr);
- ......
- }
- //Makesuretheproviderispublished(thesameproviderclass
- //maybepublishedundermultiplenames).
- if(firstClass){
- mProvidersByClass.put(cpi.name,cpr);
- }
- cpr.launchingApp=proc;
- mProvidersByName.put(name,cpr);
- ......
- }
- //Waitfortheprovidertobepublished...
- synchronized(cpr){
- while(cpr.provider==null){
- ......
- try{
- cpr.wait();
- }catch(InterruptedExceptionex){
- }
- }
- }
- returncpr;
- }
- ......
- }
函数首先是获取调用者的进程记录块信息:
- ProcessRecordr=null;
- if(caller!=null){
- r=getRecordForAppLocked(caller);
- ......
- }
在我们这个情景中,由于是第一次调用ArticlesProvider接口,因此,在mProvidersByName和mProvidersByClass两个Map中都不存在ArticlesProvider的相关信息,因此,这里会通过AppGlobals.getPackageManager函数来获得PackageManagerService服务接口,然后分别通过它的resolveContentProvider和getApplicationInfo函数来分别获取ArticlesProvider应用程序的相关信息,分别保存在cpi和cpr这两个本地变量中。这些信息都是在安装应用程序的过程中保存下来的,具体可以参考 Android应用程序安装过程源代码分析 一文。
- //Firstcheckifthiscontentproviderhasbeenpublished...
- cpr=mProvidersByName.get(name);
- if(cpr!=null){
- ......
- }else{
- try{
- cpi=AppGlobals.getPackageManager().
- resolveContentProvider(name,
- STOCK_PM_FLAGS|PackageManager.GET_URI_PERMISSION_PATTERNS);
- }catch(RemoteExceptionex){
- }
- ......
- }
- cpr=mProvidersByClass.get(cpi.name);
- finalbooleanfirstClass=cpr==null;
- if(firstClass){
- try{
- ApplicationInfoai=
- AppGlobals.getPackageManager().
- getApplicationInfo(
- cpi.applicationInfo.packageName,
- STOCK_PM_FLAGS);
- ......
- cpr=newContentProviderRecord(cpi,ai);
- }catch(RemoteExceptionex){
- //pmisinsameprocess,thiswillneverhappen.
- }
- }
更多相关文章
- C语言函数以及函数的使用
- android获取手机信息以及服务商信息
- Android判断应用是否存在 及 Android 关闭整个应用程序
- Android 7.0 移除设置中的某些项(辅助功能、流量使用情况、位置信
- 用Eclipse开发和调试Android应用程序(一)