android contentResolver与contentProvider怎么关联在一起的

android contentResolver与contentProvider如何关联在一起的
看到一篇文章觉得不错,推荐给大家,希望大家喜欢android contentResolver与contentProvider怎么关联在一起的

Application是一个完整的应用,比如某个apk,它对应一个Application,它里面可能包含n个Activity。

涉及到的类froyo/frameworks/base/core/java/android/app/ApplicationContext.java

          froyo/frameworks/base/core/java/android/app/ActivityThread.java

          froyo/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java


当我们启动手机之后,如果需要启动一个activity,ActivityThread,ActivityManagerService就开始发挥作用了,这里不做细述。

当我们真正的启动一个activity的时候,我们会把当前Application的ApplicationContext传进去,

ApplicationContext实例持有一个mContextResolver对象,该对象对应于ApplicationContext的

内部类ApplicationContentResolver.

当activity调用getContentResolver()时,我们实际调用的是当前ApplicationContext中的mContextResolver.

由于黑色的继承关系,我们可以得到红色的调用关系

代码片段如下:
Activity调用ContextWrapper的方法
  1.     getContentResolver() {

  2.         mBase.getContentResolver();

  3.      }
复制代码
然后会调用到ApplicationContext的方法
  1.    getContentResolver() {

  2.        return mContentResolver;

  3.      }
复制代码
其中:
  1. mContentResolve r = new ApplicationContentResolver(this, mainThread);


  2.     private static final class ApplicationContentResolver extends ContentResolver {
  3.         public ApplicationContentResolver(Context context,
  4.                                           ActivityThread mainThread)
  5.         {
  6.             super(context);
  7.             mMainThread = mainThread;
  8.         }

  9.         @Override
  10.         protected IContentProvider acquireProvider(Context context, String name)
  11.         {
  12.             return mMainThread.acquireProvider (context, name);
  13.         }

  14.         @Override
  15.         public boolean releaseProvider(IContentProvider provider)
  16.         {
  17.             return mMainThread.releaseProvider(provider);
  18.         }
  19.       
  20.         private final ActivityThread mMainThread;
  21.     }
复制代码
当执行mContentResolver.query()的时候,我们会调用父类ContentResolver的query();
  1. public final Cursor query(Uri uri, String[] projection,
  2.             String selection, String[] selectionArgs, String sortOrder) {
  3.         IContentProvider provider = acquireProvider(uri);
  4.         if (provider == null) {
  5.             return null;
  6.         }
  7.         try {
  8.             Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
  9.             if(qCursor == null) {
  10.                 releaseProvider(provider);
  11.                 return null;
  12.             }
  13.             //Wrap the cursor object into CursorWrapperInner object
  14.             return new CursorWrapperInner(qCursor, provider);
  15.         } catch (RemoteException e) {
  16.             releaseProvider(provider);
  17.             return null;
  18.         } catch(RuntimeException e) {
  19.             releaseProvider(provider);
  20.             throw e;
  21.         }
  22.     }


  23. public final IContentProvider acquireProvider(Uri uri)
  24.     {
  25.         if (!SCHEME_CONTENT.equals(uri.getScheme())) {
  26.             return null;
  27.         }
  28.         String auth = uri.getAuthority();
  29.         if (auth != null) {
  30.             return acquireProvider(mContext, uri.getAuthority());
  31.         }
  32.         return null;
  33.     }
复制代码
此时,会调用子类实例aquireProvider(Context,name);
  1. mMainThread.acquireProvider (context, name);
复制代码
实现为:
  1. public final IContentProvider acquireProvider (Context c, String name) {
  2.         IContentProvider provider = getProvider (c, name);
  3.         if(provider == null)
  4.             return null;
  5.         IBinder jBinder = provider.asBinder();  //获得binder对象,跨进程传递数据。
  6.         synchronized(mProviderMap) {
  7.             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
  8.             if(prc == null) {
  9.                 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
  10.             } else {
  11.                 prc.count++;
  12.             } //end else
  13.         } //end synchronized
  14.         return provider;
  15.     }


  16. private final IContentProvider getProvider (Context context, String name) {
  17.         synchronized(mProviderMap) {
  18.             final ProviderRecord pr = mProviderMap .get(name); //ActivityThread中持有所有的Provider的实例
  19.             if (pr != null) {
  20.                 return pr.mProvider;
  21.             }
  22.         }
  23.         //如果确实没有,则查找,并install,再没有就直接抛异常了。
  24.         IActivityManager.ContentProviderHolder holder = null;
  25.         try {
  26.             holder = ActivityManagerNative.getDefault().getContentProvider(
  27.                 getApplicationThread(), name);
  28.         } catch (RemoteException ex) {
  29.         }
  30.         if (holder == null) {
  31.             Log.e(TAG, "Failed to find provider info for " + name);
  32.             return null;
  33.         }
  34.         if (holder.permissionFailure != null) {
  35.             throw new SecurityException("Permission " + holder.permissionFailure
  36.                     + " required for provider " + name);
  37.         }

  38.         IContentProvider prov = installProvider(context, holder.provider,
  39.                 holder.info, true);
  40.         //Log.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
  41.         if (holder.noReleaseNeeded || holder.provider == null) {
  42.             // We are not going to release the provider if it is an external
  43.             // provider that doesn't care about being released, or if it is
  44.             // a local provider running in this process.
  45.             //Log.i(TAG, "*** NO RELEASE NEEDED");
  46.             synchronized(mProviderMap) {
  47.                 mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
  48.             }
  49.         }
  50.         return prov;
  51.     }
复制代码
到这里的话,ContentResovler与ContentProvider的关系就搞懂了,具体其他的细节,将分为不同的方面,分别讲述。