ContentProvider的工作过程

本文详细介绍了Android中ContentProvider的启动及工作流程,包括如何通过ContentResolver访问ContentProvider,以及从进程启动到ContentProvider实例化的全过程。
摘要由CSDN通过智能技术生成

ContentProvider的工作过程

ContentProvider的调用过程

ContentProvider的调用流程图

ContentProvider所在的进程启动时,ContentProvider会同时启动并发布到AMS中。ContentProvider的onCreate要先于Application的onCreate而执行。

访问ContentProvider需要通过ContentResolver,ContentResolver是一个抽象类,实际实现者是ContentImpl中的ApplicationContentResolver

private static final class ApplicationContentResolver extends ContentResolver {

    @Override
    protected IContentProvider acquireProvider(Context context, String auth) {
        return mMainThread.acquireProvider(context,
                ContentProvider.getAuthorityWithoutUserId(auth),
                resolveUserIdFromAuthority(auth), true);
    }

    //...
}  

通过ContentResolver的四个方法的任意一个,都可以触发ContentProvider的启动(如果还没有启动的话)

这里以query()示例

public final Cursor query(final Uri uri, String[] projection,
        String selection, String[] selectionArgs, String sortOrder,
        CancellationSignal cancellationSignal) {
    IContentProvider unstableProvider = acquireUnstableProvider(uri);
    IContentProvider stableProvider = null;
    //...
    try {
        qCursor = unstableProvider.query(mPackageName, uri, projection,
                selection, selectionArgs, sortOrder, remoteCancellationSignal);
    } catch (DeadObjectException e) {
        stableProvider = acquireProvider(uri);
        qCursor = stableProvider.query(mPackageName, uri, projection,
                selection, selectionArgs, sortOrder, remoteCancellationSignal);
    }
     //...
}  

可以看到,先调用了acquireUnstableProvider(),如果失败,则会调用acquireProvider(),但最终都是通过acquireProvider()来获取ContentProvider

ApplicationContentResolver的acquireProvider方法并没有处理任何逻辑,它直接调用了ActivityThread的acquireProvider()

来看ActivityThread#acquireProvider()

public final IContentProvider acquireProvider(
        Context c, String auth, int userId, boolean stable) {
    //查找是否已经存在目标ContentProvider,如果存在就直接返回
    final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);

    //启动ContentProvider
    holder = ActivityManagerNative.getDefault().getContentProvider(
            getApplicationThread(), auth, userId, stable);

    //安装Provider,增加引用的数量
    holder = installProvider(c, holder, holder.info,
            true /*noisy*/, holder.noReleaseNeeded, stable);
    return holder.provider;
}

启动ContentProvider的过程

启动ContentProvider的过程

ContentProvider启动之前,会前启动ContentProvider的进程

启动进程由ActivityManagerService的startProcessLocked()来完成,其内部主要通过Process的start方法来完成一个新进程的启动。

新进程启动后其入口为ActivityThread的main方法。

public static void main(String[] args) {
    //...
    //Z-创建主线程的消息队列
    Looper.prepareMainLooper();

    //Z-创建ActivityThread实例
    ActivityThread thread = new ActivityThread();
    //Z-远程调用AMS的attachApplication方法,进行初始化,并将ApplicationThread对象提供给AMS
    thread.attach(false);

    //...
    Looper.loop();
}  

来看ActivityThread#attach()

private void attach(boolean system) {
    final IActivityManager mgr = ActivityManagerNative.getDefault();
    mgr.attachApplication(mAppThread);  
    //...
}

再来看ActivityManagerService.attachApplication()

public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}  

再来看ActivityManagerService.attachApplicationLocked()

private final boolean attachApplicationLocked(IApplicationThread thread,
                                              int pid) {

    //...
    //Z- ApplicationThread.bindApplication
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
            app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
            mCoreSettingsObserver.getCoreSettingsLocked());

    //...
    return true;
}  

再来看ApplicationThread.bindApplication()

public final void bindApplication(String processName, ApplicationInfo appInfo,
            List<ProviderInfo> providers, ComponentName instrumentationName,
            ProfilerInfo profilerInfo, Bundle instrumentationArgs,
            IInstrumentationWatcher instrumentationWatcher,
            IUiAutomationConnection instrumentationUiConnection, int debugMode,
            boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
            Bundle coreSettings) {

        //...
        //Z- 通过ActivityThread的mH Handler切换到ActivityThread中去执行
        sendMessage(H.BIND_APPLICATION, data);
    }  

Message的发送通过handleBindApplication()来处理

 private void handleBindApplication(AppBindData data) {
    //... 
    //1.创建ContextImpl和Instrumentation
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    //...

    //2.创建Application对象
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app;

    //3.启动当前进程的ContentProvider并调用其onCreate方法
    List<ProviderInfo> providers = data.providers;
    if (providers != null) {
        installContentProviders(app, providers);
        mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
    }

    //4.调用Application的onCreate方法
    mInstrumentation.callApplicationOnCreate(app);
}  

其中会调用 installContentProviders()

private void installContentProviders(
        Context context, List<ProviderInfo> providers) {

    //...
    //通过类加载器完成ContentProvider的创建
    IActivityManager.ContentProviderHolder cph = installProvider(context, 
    //...
    //通过AMS存储到Map中
    ActivityManagerNative.getDefault().publishContentProviders(
        getApplicationThread(), results);
}  

又会调用installProvider()

private IActivityManager.ContentProviderHolder installProvider(Context context,
    IActivityManager.ContentProviderHolder holder, ProviderInfo info,
    boolean noisy, boolean noReleaseNeeded, boolean stable) {

    //通过类加载器完成ContentProvider的创建
    final java.lang.ClassLoader cl = c.getClassLoader();
    localProvider = (ContentProvider)cl.
        loadClass(info.name).newInstance();
    provider = localProvider.getIContentProvider();

    //该方法会调用ContentProvider的onCrate方法
    localProvider.attachInfo(c, info);

    return retHolder;
}

通过调用提供的接口来访问ContentProvider

ContentProvider#query()

public Cursor query(String callingPkg, Uri uri, String[] projection,
    String selection, String[] selectionArgs, String sortOrder,
    ICancellationSignal cancellationSignal) {
    //...
    return ContentProvider.this.query(
            uri, projection, selection, selectionArgs, sortOrder,
            CancellationSignal.fromTransport(cancellationSignal));
    //...
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值