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的方法

     getContentResolver() {

        mBase.getContentResolver();

     }

然后會調用到ApplicationContext的方法

     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;
    }

 

 

當執行mContentResolver.query()的時候,我們會調用父類ContentResolver的query();

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;
    }

 

此時,會調用子類實例aquireProvider(Context,name);

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;
    }

 

到這里的話,ContentResovler與ContentProvider的關系就搞懂了,具體其他的細節,將分為不同的方面,分別講述。

 

轉自:http://blog.csdn.net/yangxinle137/article/details/5985608


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM