【源码阅读】ContentResolver

因为要找一找 ContentResolver 的具体实现是在哪里的,因此拜读了下 Android 的源码,以下就是拜读过程和思路

getContentResolver() 是定义在 Context 里的, 以下是 Context 的源码

    /** Return a ContentResolver instance for your application's package. */
    public abstract ContentResolver getContentResolver();

从关键字 abstract 可以看出 getContentResolver() 是一个抽象方法, 也就是说在子类当中,必然有具体的代码实现

于是沿着 Activity 的继承链找

Context 子类 ContextWrapper源码找到了下面的实现语句:

    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }

原来 ContextWrappergetContentResolver 外包出去给 mBase, 这里编程当中的设计模式 委托模式,将 getContentResolver 交给 mBase 来实现

这时就需从 ContextWrapper(本类中) 找出 mBase 是什么鬼

于是又找到了下面的赋值方法:

    /**
     * Set the base context for this ContextWrapper.  All calls will then be
     * delegated to the base context.  Throws
     * IllegalStateException if a base context has already been set.
     * 
     * @param base The new base context for this wrapper.
     */
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

于是就指道了 attachBaseContext 是设置 mBase 的,这时还未弄得懂 mBase 是什么鬼,需要找出谁调用了 attachBaseContext 这个方法,并且传递了什么样的参数,才能弄懂

然后在 Activity源码 中找到 attachBaseContext 的调用了,原来是 attach 语句进行了调用

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {

        // 就是这句了
        attachBaseContext(context);

这时就接触真相了

每次 App 启动的时候,都会调用 Activity 的 attach 方法,而 attach 方法,传入的 context 就是类 ContextImp 了,它的源码里有 getContentResolver 的实现方法:

    @Override
    public ContentResolver getContentResolver() {
        return mContentResolver;
    }

ContextImp 里面也有下面的这一句代码,对 mContentResolver 进行赋值,就是这句创造了 Resolver 的了,到此我们就找出了 Resolver 了

mContentResolver = new ApplicationContentResolver(this, mainThread, user);

ContextImp 也有类 ApplicationContentResolver 的实现,这里就不提下去了

接着就是 ActivityThread 类里面有如何将 Mainfest 创造 content provider 的映射表的实现代码

推荐阅读更多精彩内容