Android ContentProvider启动流程源码解析(8.0)

本文详细探讨了Android ContentProvider的启动流程,从入口点开始,经过AMS处理,到ActivityThread$main的分析,再到ContentProvider启动后的query操作,深入理解ContentProvider的工作原理。
摘要由CSDN通过智能技术生成

一,写在前面

       在文章 Android 如何自定义一个ContentProvider中,介绍了如何使用以及自定义一个ContentProvider,本篇不再介绍如何使用ContentProvider访问其他应用的数据。在阅读本篇文章前,建议先了解Activity的启动流程,可参考文章  Android Activity的启动流程源码解析(8.0) ,将不再对重复的代码细节进行分析。


二,启动ContentProvider的入口

       如何启动一个ContentProvider呢?在一个Activity类中,可以调用getContentResolver().query(...)查询指定uri对应的数据,在这个过程中若ContentProvider没有启动,则会启动ContentProvider。当然,相应的insert,delete,update方法也可以启动ContentProvider,本篇文章以query方法为例进行分析。
       获取ContentResolver的对象,实际上调用的是ContextWrapper$getContentResolver方法,ContextWrapper是抽象类Context的一个子类。 
       查看ContextWrapper$getContentResolver方法源码:
    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }
       第3行,变量mBase对应的是ContextImpl对象,分析见 Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。
       
      查看ContextImpl$getContentResolver方法源码:
    @Override
    public ContentResolver getContentResolver() {
        return mContentResolver;
    }
       第3行,变量mContentResolver的初始化在ContextImpl的构造函数中完成,mContentResolver = new ApplicationContentResolver(this, mainThread, user),也就是返回的是ApplicationContentResolver的实例。值得一提的是,ContextImpl对象的创建是在启动Activity的流程中完成,具体分析见  Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。

       ApplicationContentResolver是ContextImpl的一个内部类,且继承类ContentResolver。调用getContentResolver().query(...)方法,是从父类ContentResolver继承的query方法。
       查看ContentResolver$query方法源码:
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
            @Nullable String[] projection, @Nullable String selection,
            @Nullable String[] selectionArgs, @Nullable String sortOrder,
            @Nullable CancellationSignal cancellationSignal) {
	    
	    //...

	    IContentProvider unstableProvider = acquireUnstableProvider(uri);
	    if (unstableProvider == null) {
                 return null;
            }
	    
	    //...
	
	    qCursor = unstableProvider.query(mPackageName, uri, projection,
                        selection, selectionArgs, sortOrder, remoteCancellationSignal);
	    
	    //...
}
       第8行,获取一个IContentProvider类型的对象unstableProvider。 启动ContentProvider从这里开始分析,后面会详细分析。
       第9行,对变量unstableProvider进行判空检查;
       第15行,根据指定uri,执行查询数据操作, 文章的最后会详细分析

       查看ContentResolver$acquireUnstableProvider方法(一个参数)源码:
public final IContentProvider acquireUnstableProvider(Uri uri) {
        if (!SCHEME_CONTENT.equals(uri.getScheme())) {
            return null;
        }
        String auth = uri.getAuthority();
        if (auth != null) {
            return acquireUnstableProvider(mContext, uri.getAuthority());
        }
        return null;
}
       第2行,对uri的scheme进行检查;
       第7行,逻辑跳到ApplicationContentResolver$acquireUnstableProvider方法(两个参数);

       查看ApplicationContentResolver$acquireUnstableProvider方法源码:
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
    return mMainThread.acquireProvider(c,
	    ContentProvider.getAuthorityWithoutUserId(auth),
	    resolveUserIdFromAuthority(auth), false);
}
       第3行,变量mMainThread是一个ActivityThread类型的对象,该变量的初始化也是在ContextImpl的构造函数中完成。

       查看ActivityThread$acquireProvider方法源码:
    public final IContentProvider acquireProvider(
            Context c, String auth, int userId, boolean stable) {
        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
        if (provider != null) {
            return provider;
        }
        ContentProviderHolder holder = null;
        
	//...

        holder = ActivityManager.getService().getContentProvider(
                    getApplicationThread(), auth, userId, stable);
        
	//...

        holde
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值