您的位置:首页 > 编程语言 > PHP开发

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));
//...
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息