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的方法
复制代码
然后会调用到ApplicationContext的方法
复制代码
其中:
复制代码
当执行mContentResolver.query()的时候,我们会调用父类ContentResolver的query();
复制代码
此时,会调用子类实例aquireProvider(Context,name);
复制代码
实现为:
复制代码
到这里的话,ContentResovler与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的方法
- getContentResolver() {
- mBase.getContentResolver();
- }
- getContentResolver() {
- return mContentResolver;
- }
- mContentResolve r = new ApplicationContentResolver(this, mainThread);
- private static final class ApplicationContentResolver extends ContentResolver {
- public ApplicationContentResolver(Context context,
- ActivityThread mainThread)
- {
- super(context);
- mMainThread = mainThread;
- }
- @Override
- protected IContentProvider acquireProvider(Context context, String name)
- {
- return mMainThread.acquireProvider (context, name);
- }
- @Override
- public boolean releaseProvider(IContentProvider provider)
- {
- return mMainThread.releaseProvider(provider);
- }
-
- private final ActivityThread mMainThread;
- }
- public final Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- IContentProvider provider = acquireProvider(uri);
- if (provider == null) {
- return null;
- }
- try {
- Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
- if(qCursor == null) {
- releaseProvider(provider);
- return null;
- }
- //Wrap the cursor object into CursorWrapperInner object
- return new CursorWrapperInner(qCursor, provider);
- } catch (RemoteException e) {
- releaseProvider(provider);
- return null;
- } catch(RuntimeException e) {
- releaseProvider(provider);
- throw e;
- }
- }
- public final IContentProvider acquireProvider(Uri uri)
- {
- if (!SCHEME_CONTENT.equals(uri.getScheme())) {
- return null;
- }
- String auth = uri.getAuthority();
- if (auth != null) {
- return acquireProvider(mContext, uri.getAuthority());
- }
- return null;
- }
- mMainThread.acquireProvider (context, name);
- public final IContentProvider acquireProvider (Context c, String name) {
- IContentProvider provider = getProvider (c, name);
- if(provider == null)
- return null;
- IBinder jBinder = provider.asBinder(); //获得binder对象,跨进程传递数据。
- synchronized(mProviderMap) {
- ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if(prc == null) {
- mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
- } else {
- prc.count++;
- } //end else
- } //end synchronized
- return provider;
- }
- private final IContentProvider getProvider (Context context, String name) {
- synchronized(mProviderMap) {
- final ProviderRecord pr = mProviderMap .get(name); //ActivityThread中持有所有的Provider的实例
- if (pr != null) {
- return pr.mProvider;
- }
- }
- //如果确实没有,则查找,并install,再没有就直接抛异常了。
- IActivityManager.ContentProviderHolder holder = null;
- try {
- holder = ActivityManagerNative.getDefault().getContentProvider(
- getApplicationThread(), name);
- } catch (RemoteException ex) {
- }
- if (holder == null) {
- Log.e(TAG, "Failed to find provider info for " + name);
- return null;
- }
- if (holder.permissionFailure != null) {
- throw new SecurityException("Permission " + holder.permissionFailure
- + " required for provider " + name);
- }
- IContentProvider prov = installProvider(context, holder.provider,
- holder.info, true);
- //Log.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
- if (holder.noReleaseNeeded || holder.provider == null) {
- // We are not going to release the provider if it is an external
- // provider that doesn't care about being released, or if it is
- // a local provider running in this process.
- //Log.i(TAG, "*** NO RELEASE NEEDED");
- synchronized(mProviderMap) {
- mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
- }
- }
- return prov;
- }