ContentProvider

参考:

理解ContentProvider原理 - Gityuan博客 | 袁辉辉的技术博客

App端进程创建后,执行ActivityThread.main();

        创建ActivityThread实例,并执行attach();

                通知AMS本进程创建完成了,AMS.attachApplication(mAppThread, startSeq);

AMS的attachApplicationLock中,会找到这个app的provider,并传回给ActivityThread

AMS {
    attachApplicationLocked() {
        List<ProviderInfo> providers = null;
        providers = generateApplicationProvidersLocked(app);

        //调回App端
        thread.bindApplication(processName, appInfo, providers, ...);
    }

    //找providers
    generateApplicationProvidersLocked() {
        providers = AppGlobals.getPackageManager() //就是PMS
                    .queryContentProviders(...);
    }
}

PMS中找

PMS {
    ParceledListSlice<ProviderInfo> queryContentProviders(...) {
        
    }
}

  App端,安装provider

ActivityThread {
    handleBindApplication(...) {
        ...
        //创建application的context,其中会创建contentResolver
        ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

        //安装本app中的provider
        app = data.info.makeApplication(..);
        if (!data.restrictedBackupMode) { //从ams传回来的,表示本app正在备份或恢复。
            if (!ArrayUtils.isEmpty(data.providers)) {
                //
                installContentProviders(app, data.providers);
            }
        }
    }
}

app端生成contentResolver

ContextImpl {
    createAppContext(...) {
        ...
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null, opPackageName);
    }

    private ContextImpl(...) {
        ...
        mContentResolver = new ApplicationContentResolver(this, mainThread);
    }
}

创建ContentResolver。

ContextImpl {
    class ApplicationContentResolver extends ContentResolver {
        ApplicationContentResolver(Context context, ActivityThread mainThread) {
            super(context); //mWrapped = null
            mMainThread = Preconditions.checkNotNull(mainThread);
        }
    }
}

安装provider,告诉ams哪些provider安装成功了

ActivityThread {
    installContentProviders(Context, List<ProviderInfo> providers) {
        for () {
            ContentProviderHolder cph = installProvider(context, null, cpi, ...);
            result.add(cph);
        }
    
        //再告诉AMS,本app成功安装了哪些contentProvider
        ActivityManager.getService().publishContentProviders(getApplicationThread(), results);
    }
}

安装provider

ActivityThread {
    installProvider(., ContentProviderHolder holder, ProviderInfo info, .) {
        ContentProvider localProvider;
        IContentProvider provider; //是ContentProvider里的binder
        
        //cl=classLoader,info.name是AndroidManifest.xml中provider的android:name。这里通过反射,生成provider的实例。
        localProvider = packageInfo.getAppFactory().instantiateProvider(cl, info.name);

        provider = localProvider.getIContentProvider();

        if (localProvider != null) {
            ProviderClientRecord pr = mLocalProviderByName.get(cname); // cname=ComponentName,是provider的cn。
            if (pr != null) {
            } else {
                holder = new ContentProviderHolder(info);
                holder.provider = provider;
                holder.noReleaseNeeded = true;
                pr = installProviderAuthoritiesLocked(provider, localProvider, holder);

                mLocalProvidersByName.put(cname, pr);
            }
            retHolder = pr.mHolder; //就是上面的holder
        }
        return retHolder;
    }
}

告诉ams,app的准备好了哪些provider

AMS {
    publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers) {
        for () {
            ContentProviderHolder src = providers.get(i);

            // attachApplication时,ams找到app中所有provider,然后保存到r= ProcessRecord的pubProviders中
            ContentProviderRecord dst = r.pubProviders.get(src.info.name);

            if (dst != null) {
                dst.notifyAll();
            }
            
        }
    }
}

query

对query这个行为,有个坑。

unstableProvider,那个Provider进程挂了,不会影响自己。

stableProvider,那个Provider挂了,自己也会被kill。

ContentResolver {
    query(Uri uri, ...) {
        IContentProvider unstableProvider = acquireUnstableProvider(uri);
        
        try {
            qCursor = unstableProvider.query(mPackageName, uri, projection,
                        queryArgs, remoteCancellationSignal);
        } catch(DeadObjectException e) {
            stableProvider = acquireProvider(uri); //对query这个动作,先用unstableProvider,失败的话就用stable provider
            qCursor = stableProvider.query(
                        mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
        }
        
        CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
        return wrapper;
    }
}

unstable或者stable的Provider,会调用相同的ActivityThread.acquireProvider方法,参数不同。

//最终是到ActivityThread中,获取provider
ActivityThread {
    IContentProvider acquireProvider(Context c, String auth, int userId,
            boolean stable) {
        //从已经安装的provider里取

        //从ams里,获取ContentProviderHolder
        ContontProviderHolder holder = null;
        holder = ActivityManager.getService().getContentProvider(...);

        //安装这个holder
        holder = installProvider(c, holder, ...); //c=context。holder就是上面的holder
        
        return holder.provider; //返回的provider,是从ams获取的,是提供者的binder
    }
}

从AMS里,获取holder

AMS {
    ContentProviderHolder getContentProvider(IApplicationThread caller, String callingName, 
 String name, int userId, boolean stable) {
        return getContentProviderImpl(caller, ...);
    }

    //
    getContentProviderImpl(...) {
        ...
        cpr = mProviderMap.getProviderByName(name, userId); //name就是authority,根据authority和userId,获取contentProviderRecord

        ContentProviderConnection conn = null;
        
        // provider没有运行
        if (providerRunning) {
            if (r != null && cpr.canRunHere(r)) {//provider能在调用端运行,一般不可以
                ...

                ContentProviderHolder holder = cpr.newHolder(null);
                return holder;
            }

            //生成ContentProviderConnection,这个connection里保存了contentProviderRecord和调用者的ProcessRecord。
            conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, stable);
        }

        ...

        return cpr.newHolder(conn);
            
    }
}

生成contentProviderConnection

AMS {
    ContentProviderConnection incProviderCountLocked(ProcessRecord r, ContentProviderRecord cpr, ...) {
        ...
        ContentProviderConnection conn = new ContentProviderConnection(cpr, r, callingPackage);
        if (stable) {
            conn.stableCount = 1;
            conn.numStableIncs = 1;
        }

        cpr.connextions.add(conn);
        r.conProviders.add(conn);

        return conn;
    }
}

安装Provider

ActivityThread {
    installProvider(Context context, ContentProviderHolder holder, ..., boolean stable) {
        
        IContentProvider provider;

        if (holder == null || holder.provider == null) {//从ams获取到的holder不是null
        } else {
            provider = holder.provider; //是provder的binder
        }

        IBinder jBinder = provider.asBinder();
        if (localProvider != null) {
        } else {
            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
            if (prc != null) {
            } else {
                //生成client的同时,保存到mProviderMap里。
                ProviderClientRecord client = installProviderAuthoritiesLocked(
                            provider, localProvider, holder);

                //stable决定后2个参数。
                prc = new ProviderRefCount(holder, client, 1, 0);
            }
        }
    }
}

--留白

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值