ContentProvider的工作过程

来源:互联网 发布:iphone酷狗网络异常 编辑:程序博客网 时间:2024/04/30 00:23

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));    //...}  
0 0
原创粉丝点击