Step 7.ActivityManagerService.getContentProviderImpl 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
        
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalContentProviderHoldergetContentProviderImpl(
  5. IApplicationThreadcaller,Stringname){
  6. ContentProviderRecordcpr;
  7. ProviderInfocpi=null;
  8. synchronized(this){
  9. ProcessRecordr=null;
  10. if(caller!=null){
  11. r=getRecordForAppLocked(caller);
  12. ......
  13. }
  14. //Firstcheckifthiscontentproviderhasbeenpublished...
  15. cpr=mProvidersByName.get(name);
  16. if(cpr!=null){
  17. ......
  18. }else{
  19. try{
  20. cpi=AppGlobals.getPackageManager().
  21. resolveContentProvider(name,
  22. STOCK_PM_FLAGS|PackageManager.GET_URI_PERMISSION_PATTERNS);
  23. }catch(RemoteExceptionex){
  24. }
  25. ......
  26. }
  27. cpr=mProvidersByClass.get(cpi.name);
  28. finalbooleanfirstClass=cpr==null;
  29. if(firstClass){
  30. try{
  31. ApplicationInfoai=
  32. AppGlobals.getPackageManager().
  33. getApplicationInfo(
  34. cpi.applicationInfo.packageName,
  35. STOCK_PM_FLAGS);
  36. ......
  37. cpr=newContentProviderRecord(cpi,ai);
  38. }catch(RemoteExceptionex){
  39. //pmisinsameprocess,thiswillneverhappen.
  40. }
  41. }
  42. if(r!=null&&cpr.canRunHere(r)){
  43. //Ifthisisamultiprocessprovider,thenjustreturnits
  44. //infoandallowthecallertoinstantiateit.Onlydo
  45. //thisiftheprovideristhesameuserasthecaller's
  46. //process,orcanrunasroot(socanbeinanyprocess).
  47. returncpr;
  48. }
  49. ......
  50. //Thisissingleprocess,andourappisnowconnectingtoit.
  51. //Seeifwearealreadyintheprocessoflaunchingthis
  52. //provider.
  53. finalintN=mLaunchingProviders.size();
  54. inti;
  55. for(i=0;i<N;i++){
  56. if(mLaunchingProviders.get(i)==cpr){
  57. break;
  58. }
  59. }
  60. //Iftheproviderisnotalreadybeinglaunched,thengetit
  61. //started.
  62. if(i>=N){
  63. finallongorigId=Binder.clearCallingIdentity();
  64. ProcessRecordproc=startProcessLocked(cpi.processName,
  65. cpr.appInfo,false,0,"contentprovider",
  66. newComponentName(cpi.applicationInfo.packageName,
  67. cpi.name),false);
  68. ......
  69. mLaunchingProviders.add(cpr);
  70. ......
  71. }
  72. //Makesuretheproviderispublished(thesameproviderclass
  73. //maybepublishedundermultiplenames).
  74. if(firstClass){
  75. mProvidersByClass.put(cpi.name,cpr);
  76. }
  77. cpr.launchingApp=proc;
  78. mProvidersByName.put(name,cpr);
  79. ......
  80. }
  81. //Waitfortheprovidertobepublished...
  82. synchronized(cpr){
  83. while(cpr.provider==null){
  84. ......
  85. try{
  86. cpr.wait();
  87. }catch(InterruptedExceptionex){
  88. }
  89. }
  90. }
  91. returncpr;
  92. }
  93. ......
  94. }
这个函数比较长,我们一步一步地分析。
函数首先是获取调用者的进程记录块信息:
  1. ProcessRecordr=null;
  2. if(caller!=null){
  3. r=getRecordForAppLocked(caller);
  4. ......
  5. }
在我们这个情景中,要获取的就是应用程序Article的进程记录块信息了,后面会用到。 在ActivityManagerService中,有两个成员变量是用来保存系统中的Content Provider信息的,一个是mProvidersByName,一个是mProvidersByClass,前者是以Content Provider的authoriry值为键值来保存的,后者是以Content Provider的类名为键值来保存的。一个Content Provider可以有多个authority,而只有一个类来和它对应,因此,这里要用两个Map来保存,这里为了方便根据不同条件来快速查找而设计的。下面的代码就是用来检查要获取的Content Provider是否已经加存在的了:
        
  1. //Firstcheckifthiscontentproviderhasbeenpublished...
  2. cpr=mProvidersByName.get(name);
  3. if(cpr!=null){
  4. ......
  5. }else{
  6. try{
  7. cpi=AppGlobals.getPackageManager().
  8. resolveContentProvider(name,
  9. STOCK_PM_FLAGS|PackageManager.GET_URI_PERMISSION_PATTERNS);
  10. }catch(RemoteExceptionex){
  11. }
  12. ......
  13. }
  14. cpr=mProvidersByClass.get(cpi.name);
  15. finalbooleanfirstClass=cpr==null;
  16. if(firstClass){
  17. try{
  18. ApplicationInfoai=
  19. AppGlobals.getPackageManager().
  20. getApplicationInfo(
  21. cpi.applicationInfo.packageName,
  22. STOCK_PM_FLAGS);
  23. ......
  24. cpr=newContentProviderRecord(cpi,ai);
  25. }catch(RemoteExceptionex){
  26. //pmisinsameprocess,thiswillneverhappen.
  27. }
  28. }
在我们这个情景中,由于是第一次调用ArticlesProvider接口,因此,在mProvidersByName和mProvidersByClass两个Map中都不存在ArticlesProvider的相关信息,因此,这里会通过AppGlobals.getPackageManager函数来获得PackageManagerService服务接口,然后分别通过它的resolveContentProvider和getApplicationInfo函数来分别获取ArticlesProvider应用程序的相关信息,分别保存在cpi和cpr这两个本地变量中。这些信息都是在安装应用程序的过程中保存下来的,具体可以参考 Android应用程序安装过程源代码分析 一文。

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. android下usb框架系列文章---(3)Storage框架整理
  4. Android、JUnit深入浅出(七)——总…
  5. Android判断应用是否存在 及 Android(安卓)关闭整个应用程序
  6. android 自动更新网址保存
  7. Android(安卓)中处理POWER/HOME流程
  8. android用sharepreference保存输入框中的内容
  9. Android(安卓)Camera调用过程分析

随机推荐

  1. Android(安卓)Architecture LifeCycle
  2. Android(安卓)Wi-Fi Peer-to-Peer(Android
  3. Android(安卓)Handler、Looper、Message
  4. Android的Handler总结
  5. wzplayer for android V1.5 整合硬解码(
  6. Android音视频学习路线
  7. Android学习路线指南
  8. Android(安卓)进阶 教你打造 Android(安
  9. (转)ANDROID强制锁定竖屏_APP固定设置竖屏
  10. Android多媒体编程从初学到精通