Step 17.ActivityThread.installProvider 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
        
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalIContentProviderinstallProvider(Contextcontext,
  4. IContentProviderprovider,ProviderInfoinfo,booleannoisy){
  5. ContentProviderlocalProvider=null;
  6. if(provider==null){
  7. ......
  8. Contextc=null;
  9. ApplicationInfoai=info.applicationInfo;
  10. if(context.getPackageName().equals(ai.packageName)){
  11. c=context;
  12. }elseif(mInitialApplication!=null&&
  13. mInitialApplication.getPackageName().equals(ai.packageName)){
  14. c=mInitialApplication;
  15. }else{
  16. try{
  17. c=context.createPackageContext(ai.packageName,
  18. Context.CONTEXT_INCLUDE_CODE);
  19. }catch(PackageManager.NameNotFoundExceptione){
  20. }
  21. }
  22. ......
  23. try{
  24. finaljava.lang.ClassLoadercl=c.getClassLoader();
  25. localProvider=(ContentProvider)cl.
  26. loadClass(info.name).newInstance();
  27. provider=localProvider.getIContentProvider();
  28. ......
  29. //XXXNeedtocreatethecorrectcontextforthisprovider.
  30. localProvider.attachInfo(c,info);
  31. }catch(java.lang.Exceptione){
  32. ......
  33. }
  34. }elseif(localLOGV){
  35. ......
  36. }
  37. synchronized(mProviderMap){
  38. //Cachethepointerfortheremoteprovider.
  39. Stringnames[]=PATTERN_SEMICOLON.split(info.authority);
  40. for(inti=0;i<names.length;i++){
  41. ProviderClientRecordpr=newProviderClientRecord(names[i],provider,
  42. localProvider);
  43. try{
  44. provider.asBinder().linkToDeath(pr,0);
  45. mProviderMap.put(names[i],pr);
  46. }catch(RemoteExceptione){
  47. returnnull;
  48. }
  49. }
  50. if(localProvider!=null){
  51. mLocalProviders.put(provider.asBinder(),
  52. newProviderClientRecord(null,provider,localProvider));
  53. }
  54. }
  55. returnprovider;
  56. }
  57. ......
  58. }
这个函数的作用主要就是在应用程序进程中把相应的Content Provider类加载进来了,在我们这个种情景中,就是要在ArticlesProvider这个应用程序中把ArticlesProvider这个Content Provider类加载到内存中来了:
        
  1. finaljava.lang.ClassLoadercl=c.getClassLoader();
  2. localProvider=(ContentProvider)cl.
  3. loadClass(info.name).newInstance();
接着通过调用localProvider的getIContentProvider函数来获得一个Binder对象,这个Binder对象返回给installContentProviders函数之后,就会传到ActivityManagerService中去,后续其它应用程序就是通过获得这个Binder对象来和相应的Content Provider进行通信的了。我们先看一下这个函数的实现,然后再回到installProvider函数中继续分析。

Step 18. ContentProvider.getIContentProvider 这个函数定义在frameworks/base/core/java/android/content/ContentProvider.java文件中:
        
  1. publicabstractclassContentProviderimplementsComponentCallbacks{
  2. ......
  3. privateTransportmTransport=newTransport();
  4. ......
  5. classTransportextendsContentProviderNative{
  6. ......
  7. }
  8. publicIContentProvidergetIContentProvider(){
  9. returnmTransport;
  10. }
  11. ......
  12. }

从这里我们可以看出,ContentProvider类和Transport类的关系就类似于ActivityThread和ApplicationThread的关系,其它应用程序不是直接调用ContentProvider接口来访问它的数据,而是通过调用它的内部对象mTransport来间接调用ContentProvider的接口,这一点我们在下一篇文章中分析调用Content Provider接口来获取共享数据时将会看到。
回到前面的installProvider函数中,它接下来调用下面接口来初始化刚刚加载好的Content Provider:
  1. //XXXNeedtocreatethecorrectcontextforthisprovider.
  2. localProvider.attachInfo(c,info);
同样,我们先进入到ContentProvider类的attachInfo函数去看看它的实现,然后再回到installProvider函数来。 Step 19.ContentProvider.attachInfo 这个函数定义在frameworks/base/core/java/android/content/ContentProvider.java文件中:
        
  1. publicabstractclassContentProviderimplementsComponentCallbacks{
  2. ......
  3. publicvoidattachInfo(Contextcontext,ProviderInfoinfo){
  4. /*
  5. *Onlyallowittobesetonce,soafterthecontentservicegives
  6. *thistousclientscan'tchangeit.
  7. */
  8. if(mContext==null){
  9. mContext=context;
  10. mMyUid=Process.myUid();
  11. if(info!=null){
  12. setReadPermission(info.readPermission);
  13. setWritePermission(info.writePermission);
  14. setPathPermissions(info.pathPermissions);
  15. mExported=info.exported;
  16. }
  17. ContentProvider.this.onCreate();
  18. }
  19. }
  20. ......
  21. }
这个函数很简单,主要就是根据这个Content Provider的信息info来设置相应的读写权限,然后调用它的子类的onCreate函数来让子类执行一些初始化的工作。在我们这个情景中,这个子类就是ArticlesProvide应用程序中的ArticlesProvider类了。

Step 20. ArticlesProvider.onCreate 这个函数定义在前面一篇文章 Android应用程序组件Content Provider应用实例 介绍的应用程序ArtilcesProvider源代码工程目录下,在文件为packages/experimental/ArticlesProvider/src/shy/luo/providers/articles/ArticlesProvider.java中:
  1. publicclassArticlesProviderextendsContentProvider{
  2. ......
  3. @Override
  4. publicbooleanonCreate(){
  5. Contextcontext=getContext();
  6. resolver=context.getContentResolver();
  7. dbHelper=newDBHelper(context,DB_NAME,null,DB_VERSION);
  8. returntrue;
  9. }
  10. ......
  11. }

这个函数主要执行一些简单的工作,例如,获得应用程序上下文的ContentResolver接口和创建数据库操作辅助对象,具体可以参考前面一篇文章 Android应用程序组件Content Provider应用实例

回到前面Step 17中的installProvider函数中,它接下来就是把这些在本地中加载的Content Provider信息保存下来了,以方便后面查询和使用:
  1. synchronized(mProviderMap){
  2. //Cachethepointerfortheremoteprovider.
  3. Stringnames[]=PATTERN_SEMICOLON.split(info.authority);
  4. for(inti=0;i<names.length;i++){
  5. ProviderClientRecordpr=newProviderClientRecord(names[i],provider,
  6. localProvider);
  7. try{
  8. provider.asBinder().linkToDeath(pr,0);
  9. mProviderMap.put(names[i],pr);
  10. }catch(RemoteExceptione){
  11. returnnull;
  12. }
  13. }
  14. if(localProvider!=null){
  15. mLocalProviders.put(provider.asBinder(),
  16. newProviderClientRecord(null,provider,localProvider));
  17. }
  18. }

和ActivityMangerService类似,在ActivityThread中,以Content Provider的authority为键值来把这个Content Provider的信息保存在mProviderMap成员变量中,因为一个Content Provider可以对应多个authority,因此这里用一个for循环来处理,同时又以这个Content Provider对应的Binder对象provider来键值来把这个Content Provider的信息保存在mLocalProviders成员变量中,表明这是一个在本地加载的Content Provider。

更多相关文章

  1. C语言函数以及函数的使用
  2. [Android Studio] Android Studio如何提示函数用法
  3. Android 驱动之旅 第四章:在Android 系统中编写JNI 方法在应用程
  4. Android Wear应用程序开发的简要说明,对每个初学者和中级android
  5. (一)Android应用程序及组件简介
  6. Android应用程序资源管理器(Asset Manager)的创建过程分析
  7. Hierarchy Viewer 帮你分析应用程序UI布局
  8. Android应用程序的数据存放目录 路径
  9. 如何使Android应用程序获取系统权限

随机推荐

  1. Android API中文文档系列Manifest
  2. Android利用sqlite制作简单登录界面
  3. Google收购Skype的最好理由:Android
  4. Android android:gravity和android:layou
  5. Android 布局学习利器-Hierarchy Viewer
  6. android studio编译android M时无法使用o
  7. Android Scrollview
  8. android讲义2之输入界面
  9. Android EditText属性用法
  10. 关于GridView控件中设置大小的问题