ContentProvider的工作过程
2017-02-15 22:34
316 查看
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的进程
启动进程由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)); //... }
相关文章推荐
- ContentProvider的工作过程
- ContentProvider的工作过程
- ContentProvider 工作过程
- ContentProvider工作过程
- ContentProvider的工作过程
- [基础] 3.4 ContentProvider的工作过程
- windowsphone7推送服务工作过程
- MMU的作用及工作过程
- TLB的作用及工作过程
- 工作中的那些坑(1)——一次过滤存量数据的优化过程
- 工作中的碰到的问题,以及处理过程:
- 通俗易懂:编译器的工作过程
- Phone 通话过程中 PSensor 工作流程
- Ping的工作过程及单向Ping通的原因
- sphinx教程3__shpinx工作过程
- 从源码的角度理解四大组件的工作过程——Android开发艺术探索笔记
- 四大组件BroadcastReceiver的工作过程
- 编译器和链接器的工作过程
- DHCP工作过程的六个主要步骤
- jQuery 入门教程(20): jQuery UI 基本工作过程