Step 13. ActivityManagerService.attachApplicationLocked
         这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     private final boolean attachApplicationLocked(IApplicationThread thread,   
  6.             int pid) {   
  7.         // Find the application record that is being attached...  either via   
  8.         // the pid if we are running in multiple processes, or just pull the   
  9.         // next app record if we are emulating process with anonymous threads.   
  10.         Proce***ecord app;   
  11.         if (pid != MY_PID && pid >= 0) {   
  12.             synchronized (mPidsSelfLocked) {   
  13.                 app = mPidsSelfLocked.get(pid);   
  14.             }   
  15.         } else if (mStartingProcesses.size() > 0) {   
  16.             ......   
  17.         } else {   
  18.             ......   
  19.         }   
  20.    
  21.         ......   
  22.    
  23.         app.thread = thread;   
  24.         app.curAdj = app.setAdj = -100;   
  25.         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;   
  26.         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;   
  27.         app.forcingToForeground = null;   
  28.         app.foregroundServices = false;   
  29.         app.debugging = false;   
  30.    
  31.         ......   
  32.    
  33.         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);   
  34.         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;   
  35.    
  36.         try {   
  37.             ......   
  38.    
  39.             thread.bindApplication(processName, app.instrumentationInfo != null   
  40.                 ? app.instrumentationInfo : app.info, providers,   
  41.                 app.instrumentationClass, app.instrumentationProfileFile,   
  42.                 app.instrumentationArguments, app.instrumentationWatcher, testMode,   
  43.                 isRestrictedBackupMode || !normalMode,   
  44.                 mConfiguration, getCommonServicesLocked());   
  45.    
  46.             ......   
  47.         } catch (Exception e) {   
  48.             ......   
  49.         }   
  50.    
  51.         ......   
  52.            
  53.         return true;   
  54.     }   
  55.    
  56.     ......   
  57.    
  58.     private final List generateApplicationProvidersLocked(Proce***ecord app) {   
  59.         List providers = null;   
  60.         try {   
  61.             providers = AppGlobals.getPackageManager().   
  62.                 queryContentProviders(app.processName, app.info.uid,   
  63.                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);   
  64.         } catch (RemoteException ex) {   
  65.         }   
  66.         if (providers != null) {   
  67.             final int N = providers.size();   
  68.             for (int i=0; i<N; i++) {   
  69.                 ProviderInfo cpi =   
  70.                     (ProviderInfo)providers.get(i);   
  71.                 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);   
  72.                 if (cpr == null) {   
  73.                     cpr = new ContentProviderRecord(cpi, app.info);   
  74.                     mProvidersByClass.put(cpi.name, cpr);   
  75.                 }   
  76.                 app.pubProviders.put(cpi.name, cpr);   
  77.                 app.addPackage(cpi.applicationInfo.packageName);   
  78.                 ensurePackageDexOpt(cpi.applicationInfo.packageName);   
  79.             }   
  80.         }   
  81.         return providers;   
  82.     }   
  83.    
  84.     ......   
  85. }   
  这个函数首先是根据传进来的进程ID找到相应的进程记录块,注意,这个进程ID是应用程序ArticlesProvider的ID,然后对这个进程记录块做一些初倾始化的工作。再接下来通过调用generateApplicationProvidersLocked获得需要在这个过程中加载的Content Provider列表,在我们这个情景中,就只有ArticlesProvider这个Content Provider了。最后调用从参数传进来的IApplicationThread对象thread的bindApplication函数来执行一些应用程序初始化工作。从Android应用程序启动过程源代码分析一文中我们知道,在Android系统中,每一个应用程序进程都加载了一个ActivityThread实例,在这个ActivityThread实例里面,有一个成员变量mAppThread,它是一个Binder对象,类型为ApplicationThread,实现了IApplicationThread接口,它是专门用来和ActivityManagerService服务进行通信的。因此,调用下面语句:
  1. thread.bindApplication(processName, app.instrumentationInfo != null  
  2.     ? app.instrumentationInfo : app.info, providers,  
  3.     app.instrumentationClass, app.instrumentationProfileFile,  
  4.     app.instrumentationArguments, app.instrumentationWatcher, testMode,  
  5.     isRestrictedBackupMode || !normalMode,  
  6.     mConfiguration, getCommonServicesLocked());  
        就会进入到应用程序ArticlesProvider进程中的ApplicationThread对象的bindApplication函数中去。在我们这个情景场,这个函数调用中最重要的参数便是第三个参数providers了,它是我们要处理的对象。
        Step 14. ApplicationThread.bindApplication
        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
  1. public final class ActivityThread {   
  2.     ......   
  3.    
  4.     private final class ApplicationThread extends ApplicationThreadNative {   
  5.         ......   
  6.    
  7.         public final void bindApplication(String processName,   
  8.                 ApplicationInfo appInfo, List<ProviderInfo> providers,   
  9.                 ComponentName instrumentationName, String profileFile,   
  10.                 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,   
  11.                 int debugMode, boolean isRestrictedBackupMode, Configuration config,   
  12.                 Map<String, IBinder> services) {   
  13.             if (services != null) {   
  14.                 // Setup the service cache in the ServiceManager   
  15.                 ServiceManager.initServiceCache(services);   
  16.             }   
  17.    
  18.             AppBindData data = new AppBindData();   
  19.             data.processName = processName;   
  20.             data.appInfo = appInfo;   
  21.             data.providers = providers;   
  22.             data.instrumentationName = instrumentationName;   
  23.             data.profileFile = profileFile;   
  24.             data.instrumentationArgs = instrumentationArgs;   
  25.             data.instrumentationWatcher = instrumentationWatcher;   
  26.             data.debugMode = debugMode;   
  27.             data.restrictedBackupMode = isRestrictedBackupMode;   
  28.             data.config = config;   
  29.             queueOrSendMessage(H.BIND_APPLICATION, data);   
  30.         }   
  31.    
  32.         ......   
  33.     }   
  34.    
  35.     ......   
  36. }   
这个函数把相关的信息都封装成一个AppBindData对象,然后以一个消息的形式发送到主线程的消息队列中去等等待处理。这个消息最终是是在ActivityThread类的handleBindApplication函数中进行处理的。
         Step 15. ActivityThread.handleBindApplication
         这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
  1. public final class ActivityThread {  
  2.     ......  
  3.       
  4.     private final void handleBindApplication(AppBindData data) {  
  5.         ......  
  6.   
  7.         List<ProviderInfo> providers = data.providers;  
  8.         if (providers != null) {  
  9.             installContentProviders(app, providers);  
  10.             ......  
  11.         }  
  12.   
  13.         ......  
  14.     }  
  15.   
  16.     ......  
  17. }  
         这个函数的内容比较多,我们忽略了其它无关的部分,只关注和Content Provider有关的逻辑,这里主要就是调用installContentProviders函数来在本地安装Content Providers信息。
         Step 16. ActivityThread.installContentProviders
         这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
  1. public final class ActivityThread {   
  2.     ......   
  3.        
  4.     private final void installContentProviders(   
  5.             Context context, List<ProviderInfo> providers) {   
  6.         final ArrayList<IActivityManager.ContentProviderHolder> results =   
  7.             new ArrayList<IActivityManager.ContentProviderHolder>();   
  8.    
  9.         Iterator<ProviderInfo> i = providers.iterator();   
  10.         while (i.hasNext()) {   
  11.             ProviderInfo cpi = i.next();   
  12.             StringBuilder buf = new StringBuilder(128);   
  13.             buf.append("Pub ");   
  14.             buf.append(cpi.authority);   
  15.             buf.append(": ");   
  16.             buf.append(cpi.name);   
  17.             Log.i(TAG, buf.toString());   
  18.             IContentProvider cp = installProvider(context, null, cpi, false);   
  19.             if (cp != null) {   
  20.                 IActivityManager.ContentProviderHolder cph =   
  21.                     new IActivityManager.ContentProviderHolder(cpi);   
  22.                 cph.provider = cp;   
  23.                 results.add(cph);   
  24.                 // Don't ever unload this provider from the process.   
  25.                 synchronized(mProviderMap) {   
  26.                     mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));   
  27.                 }   
  28.             }   
  29.         }   
  30.    
  31.         try {   
  32.             ActivityManagerNative.getDefault().publishContentProviders(   
  33.                 getApplicationThread(), results);   
  34.         } catch (RemoteException ex) {   
  35.         }   
  36.     }   
  37.    
  38.     ......   
  39. }   
    这个函数主要是做了两件事情,一是调用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函数的实现。

Android应用程序组件Content Provider的启动过程源代码分析(5)相关推荐

  1. Android应用程序组件Content Provider的启动过程源代码分析(1)

             通过前面的学习,我们知道在Android系统中,Content Provider可以为不同的应用程序访问相同的数据提供统一的入口.Content Provider一般是运行在独立的进 ...

  2. Android应用程序组件Content Provider的启动过程源代码分析(6)

        Step 17. ActivityThread.installProvider         这个函数定义在frameworks/base/core/java/android/app/Act ...

  3. Android应用程序组件Content Provider的共享数据更新通知机制分析

    在Android系统中,应用程序组件Content Provider为不同的应用程序实现数据共享提供了基础设施,它主要通过Binder进程间通信机制和匿名共享内存机制来实现的.关于数据共享的另一个 话 ...

  4. Android应用程序组件Content Provider在应用程序之间共享数据的原理分析(1)

             在Android系统中,不同的应用程序是不能直接读写对方的数据文件的,如果它们想共享数据的话,只能通过Content Provider组件来实现.那么,Content Provide ...

  5. Android应用程序组件Content Provider的共享数据更新通知机制分析(3)

            3. 数据更新通知的发送过程        在前面这篇文章Android应用程序组件Content Provider应用实例介绍的应用程序Acticle中,当调用ArticlesAda ...

  6. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  7. Android系统默认Home应用程序(Launcher)的启动过程源代码分析(3)

    Step 13.  ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/ ...

  8. Android应用程序组件Content Provider简要介绍和学习计划

    在Android系统中,Content Provider作为应用程序四大组件之一,它起到在应用程序之间共享数据的作用,同时,它还是标准的数据访问接口.前面的一系列文章已经分析过Android应用程序的 ...

  9. Android应用程序组件Content Provider在应用程序之间共享数据的原理分析(2)

        Step 7. ContentProviderProxy.query       这个函数定义在frameworks/base/core/java/android/content/Conten ...

  10. Android系统默认Home应用程序(Launcher)的启动过程源代码分析(2)

    Step 10.  ActivityManagerService.systemReady 这个函数是在上面的Step 6中的ServerThread.run函数在将系统中的一系列服务都初始化完毕之后才 ...

最新文章

  1. 【微信小程序】异步请求,权重,自适应宽度并折行,颜色渐变,绝对定位
  2. 零基础可以学python吗-零基础适合学习python吗?
  3. 《基于张量网络的机器学习入门》学习笔记1
  4. gbdt如何处理多分类问题(multiclass,cart)
  5. sql2008安装包_数据库SQL2008下载与安装图文详解
  6. 服务器bios修改uefi,服务器 uefi bios设置
  7. android sha1和签名证书的学习
  8. Netty工作笔记0081---编解码器和处理器链梳理
  9. try-catch lasterr
  10. 新版本chrome浏览器带来的跨域请求cookie丢失问题
  11. 数值方法求积分 详解+模板代码
  12. 常微分方程数值解法(2)
  13. Team Queue
  14. 30个最讨人喜欢的英语赞美语句
  15. A Survey of Deep Learning-based Object Detection论文翻译 + 阅读笔记
  16. 怎么理解Web 3.0?
  17. PHP图片表情制作生成源码
  18. 寒门再难出贵子(下)
  19. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件
  20. 微软软件测试报告,windows计算器软件测试报告.doc

热门文章

  1. JVM总结(一):概念----(无节操转载,潜心学习)
  2. 寫下來,免得下次又忘了
  3. Intellij IDEA 报错java.lang.NoClassDefFoundError
  4. 面向对象组合及三大特性
  5. 性能测试工具Loadrunner使用之一(Virtual User Generato)
  6. [转载]SQL Server 2008 R2安装时选择的是windows身份验证,未选择混合身份验证的解决办法...
  7. .net中的各种委托(Delegate、Action、Func)
  8. 为什么找不到解决方案?--答案就是:转个弯 这里以“解决表示图左边缺失线条、边缘线、分割线问题”为例...
  9. TimeLine下载地址
  10. 关于suitescript 无法读取Item Number Field