广播的注册发送和接收过程
广播作为四大组件之一,使用频率没有Activity这么高,但是广播的工作过程也是有必要了解的,我们将从三个方面讲解广播,分别是注册,发送和接收
广播的注册过程
广播的注册就是广播接收者
注册自己感兴趣的广播,广播的注册分为两种,分别是动态注册和静态注册
- 静态注册在应用安装的时候由PackageManagerService来完成注册过程
- 动态注册的过程是复杂的,时序图如下所示
sequenceDiagram
调用 ->> ContextWrapper : registerReceiver
activate ContextWrapper
ContextWrapper ->> ContextImpl : registerReceiver
deactivate ContextWrapper
activate ContextImpl
ContextImpl ->> ContextImpl : registerReceiverInternal
ContextImpl ->> IActivityManager : registerReceiver
deactivate ContextImpl
activate IActivityManager
IActivityManager ->> AMS : registerReceiver
deactivate IActivityManager
activate AMS
deactivate AMS
想要动态注册广播,需要调用registerReceiver方法,它在ContextWrapper中实现
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return mBase.registerReceiver(receiver, filter, broadcastPermission,
scheduler);
}
mBase具体指向ContextImpl,ContextImpl.registerReceiver有很多个重载方法,最后会调用ContextImpl.registerReceiverInternal方法
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
//判断LoadedApk类型的mPackageInfo和上下文是否非空
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//获得rd,rd是IIntentReceiver类型,是一个Binder接口,用于广播的跨进程通信
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//没有获得rd的话就创建rd
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//调用AMS代理服务的registerReceiver方法,并将rd作为参数传进去
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
rd在LoadedApk.ReceiverDispatcher.InnerReceiver中实现final static class InnerReceiver extends IIntentReceiver.Stub
在调用AMS代理服务的registerReceiver方法的时候我们传入了IIntentReceiver类型的rd参数,这里我们不直接将广播接收者传递进去是因为注册广播是跨进程的过程,所有需要有有跨进程能力的IIntentReceiverc参与进来
接下来运行到了ActivityManagerService.registerReceiver方法
registerReceiver第一部分
-
通过getRecordForAppLocked方法获得ProcessRecord类型的callerApp变量,该变量用于描述请求AMS注册广播接收者的Activity所在的应用程序进程
callerApp = getRecordForAppLocked(caller);
-
根据传入的IntentFilter类型变量filter来得到actions列表
Iterator<String> actions = filter.actionsIterator();
-
根据actions列表和userIds来得到所有的粘性广播的intent,并且传入到stickyIntents中
while (actions.hasNext()) { String action = actions.next(); for (int id : userIds) { ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); if (stickies != null) { ArrayList<Intent> intents = stickies.get(action); if (intents != null) { if (stickyIntents == null) { stickyIntents = new ArrayList<Intent>(); } //将获得的粘性广播的Intent传入到stickyIntents中 stickyIntents.addAll(intents); } } } }
-
遍历寻找匹配的粘性广播,并且存储在allSticky中
ArrayList<Intent> allSticky = null; if (stickyIntents != null) { final ContentResolver resolver = mContext.getContentResolver(); // 遍历广播 for (int i = 0, N = stickyIntents.size(); i < N; i++) { Intent intent = stickyIntents.get(i); // Don't provided intents that aren't available to instant apps. if (instantApp && (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) { continue; } //寻找匹配参数的粘性广播 if (filter.match(resolver, intent, true, TAG) >= 0) { if (allSticky == null) { allSticky = new ArrayList<Intent>(); } allSticky.add(intent); } } }
registerReceiver第二部分
-
获得ReceiverList列表,ReceiverList继承于ArrayList,用来存储广播接收者
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
-
如果获得ReceiverList为null,创建ReceiverList
if (rl == null){ rl = new ReceiverList(this, callerApp, callingPid, callingUid,userId, receiver); }
-
创建BroadcastFilter并将rl传递进去,BroadcastFilter用来描述注册的广播接收者
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission, callingUid, userId, instantApp, visibleToInstantApps);
-
将BroadcastFilter添加到ReceiverList(将接收者添加到接收者列表)
rl.add(bf);
-
将BroadcastFilter添加到IntentResolver类型的mReceiverResolver中,当AMS接收到广播的时候可以从mReceiverResolver中找到对应的广播接收者
mReceiverResolver.addFilter(bf);
当BroadcastFilter添加到IntentResolver后,完成了广播的注册过程
广播的发送和接收过程
广播的发送和接收分为两个部分,分别是ContextImpl到AMS的调用过程和AMS到BroadcastReceiver的调用过程
ContextImpl到AMS的过程
广播的发送有多种类型,无序广播(普通广播),有序广播,粘性广播
我们以无序广播为例子来解析广播的发送过程,无序广播发送要调用sendBroadcast方法,该方法在ContextWrapper方法中实现
sequenceDiagram
调用 ->> ContextWrapper : sendBroadcast
activate ContextWrapper
ContextWrapper ->> ContextImpl : sendBroadcast
deactivate ContextWrapper
activate ContextImpl
ContextImpl ->> IActivityManager : broadcastIntent
deactivate ContextImpl
activate IActivityManager
IActivityManager ->> AMS : broadcastIntent
deactivate IActivityManager
activate AMS
AMS ->> AMS : broadcastInetntLocked
deactivate AMS
在ContextWrapper.sendBroadcast方法中调用了
mBase.sendBroadcast(intent)
mBase指向的是ContextImpl,接下来来到ContextImpl.sendBroadcast方法,该方法最后也是通过AMS的代理调用了ActivityManagerService.broadcastIntent
方法
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
在ActivityManagerService.broadcastIntent方法中执行了以下逻辑
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
//验证广播是否合法
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//执行broadcastIntentLocked方法
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
验证广播合法性执行了以下逻辑
-
判断Intent是否不为null,并且文件描述符不为null,否则抛出IllegalArgumentException
if (intent != null && intent.hasFileDescriptors() == true)
-
获得intent的flag
int flags = intent.getFlags();
-
如果系统在启动过程中
if (!mProcessesReady)
-
执行以下判断
//判断flag是否设置为 启动时只接受动态注册的广播接收者 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { //不做处理 //判断flag没有设置为 只接受动态注册的广播接收者 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent+ " before boot completion"); //抛出错误 throw new IllegalStateException("Cannot broadcast before boot completed"); }
-
接下来代码执行到broadcastIntentLocked
方法中,该方法执行了以下逻辑
-
将动态注册的广播接收者和静态注册的广播接收者按照优先级顺序存储在不同的列表中,之后将两个列表合并到receivers列表中,这样receivers列表中就包含了所有的广播接收者
-
创建BroadcastRecord对象并将receivers传递进去
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId);
-
调用BroadcastQueue的scheduleBroadcastsLocked方法
queue.enqueueParallelBroadcastLocked(r);
AMS到BroadcastReceiver的过程
sequenceDiagram
调用 ->> BroadcastQueue : scheduleBroadcastsLocked
activate BroadcastQueue
BroadcastQueue ->> BroadcastHandler : handleMessage
deactivate BroadcastQueue
activate BroadcastHandler
BroadcastHandler ->> BroadcastQueue : processNextBroadcast
deactivate BroadcastHandler
activate BroadcastQueue
BroadcastQueue ->> BroadcastQueue : deliverToRegisteredReceiverLocked
BroadcastQueue ->> BroadcastQueue : performReceiveLocked
BroadcastQueue ->> ApplicationThread : scheduleRegisteredReceiver
deactivate BroadcastQueue
activate ApplicationThread
ApplicationThread ->> InnerReceiver : performReceive
deactivate ApplicationThread
activate InnerReceiver
InnerReceiver ->> ReceiverDispatcher : performReceive
deactivate InnerReceiver
activate ReceiverDispatcher
ReceiverDispatcher ->> Args : run
deactivate ReceiverDispatcher
activate Args
Args ->> BroadcastReceiver : onReceive
deactivate Args
activate BroadcastReceiver
deactivate BroadcastReceiver
BroadcastQueue.scheduleBroadcastsLocked方法中向BroadcastHandler类型的mHandler发送一个消息,消息类型为BROADCAST_INTENT_MSG
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
这个消息在BroadcastHandler.handleMessage方法中进行处理
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
//调用此处
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
handleMessage方法中调用了processNextBroadcast方法,这个方法对无序广播和有序广播分别进行处理,目的是将广播发送给广播接收者,接下来代码来到processNextBroadcast方法中
- 判断fromMsg参数,我们知道调用processNextBroadcast方法的时候传入的fromMsg参数为true
- 将mBroadcastsScheduled变量设置为false,表示已经处理了BROADCAST_INTENT_MSG消息
- 遍历存储无序广播的列表
while (mParallelBroadcasts.size() > 0)
- 获取无序广播,
r = mParallelBroadcasts.remove(0);
,r变量是BroadcastRecord类型 -
将r变量描述的广播发送给对应的广播接收者
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
deliverToRegisteredReceiverLocked方法会先检查广播发送者和广播接收者的权限,如果通过了权限就会调用
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
接下来代码运行到performReceiveLocked方法中
-
判断广播接收者所在的应用程序进程存在并且正在运行
if (app != null) if (app.thread != null)
-
使用广播接收者所在应用程序进程来接收广播
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.repProcState);
app.thread指的是ApplicationThread,接下来我们到了ApplicationThread.scheduleRegisteredReceiver方法中,该方法调用了
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,sticky, sendingUser);
receiver是IIntentReceiver类型,是用于广播的跨进程通信,具体实现为LoadedApk.ReceiverDispatcher.InnerReceiver
IIntentReceiver和IActivityManager一样是使用了AIDL来完成进程之间的通信。
InnerReceiver继承于IIntentReceiver.Stub,我Binder通信时的服务器端,IIntentReceiver是客户端
在其performReceive方法中主要是执行了
rd.performReceive(intent, resultCode, data, extras,ordered, sticky, sendingUser);
rd是ReceiverDispatcher类型,代码在ReceiverDispatcher.performReceive中执行了
-
将广播的intent对象等信息封装为Args对象
final Args args = new Args(intent, resultCode, data, extras, ordered,sticky, sendingUser);
-
调用mActivityThread的post方法并且传入Args对象
if (intent == null || !mActivityThread.post(args.getRunnable()))
mActivityThread是Handler对象,指向了H类
这一段代码的意思就是将Args对象的getRunnable方法通过H类发送到线程的消息队列中
接下来来到Args.getRunnable方法中,该方法中主要执行了BroadcastReceiver对象的onReceive方法
receiver.onReceive(mContext, intent);
这样注册的广播接收者就接收到了广播并且得到了intent
ContentProvider的启动过程
内容提供者没有其他的组件使用频繁,主要是用于进程内和进程间的数据共享,ContentProvider分为两个部分
- query方法到AMS的调用过程
- AMS启动ContentProvider的过程
query到AMS的调用过程
流程图
sequenceDiagram
调用 ->> ContentResolver : query
activate ContentResolver
ContentResolver ->> ContentResolver : acquireUnstableProvider
ContentResolver ->> ApplicationContentResolver : acquireUnstableProvider
deactivate ContentResolver
activate ApplicationContentResolver
ApplicationContentResolver ->> ActivityThread : acquireProvider
deactivate ApplicationContentResolver
activate ActivityThread
ActivityThread ->> IActivityManager : getContentProvider
deactivate ActivityThread
activate IActivityManager
IActivityManager ->> AMS : getContentProvider
deactivate IActivityManager
activate AMS
AMS ->> AMS : getContentProviderImpl
AMS ->> ActivityThread : main
deactivate AMS
activate ActivityThread
ActivityThread ->> ActivityThread : attach
ActivityThread ->> IActivityManager : attachApplication
deactivate ActivityThread
activate IActivityManager
IActivityManager ->> AMS : attachApplication
deactivate IActivityManager
activate AMS
deactivate AMS
为了方便理解ContentProvider的启动过程,先解释一下如何调用ContentProvider
//准备ContentResolver
ContentResolver cr = getContentResolver();
//uri
Uri uri = Uri.parse("content://hello_world");
//向数据库中增加的数据的值
ContentValues values = new ContentValues();
values.put("_name", "Susan");
values.put("_age", 44);
values.put("_phone", "14444444444");
values.put("_email", "test@text.org");
//执行增加
cr.insert(uri, values);
上面的代码向着Uri指向的内容提供者插入了一条数据,我们插入一条数据,需要使用ContentResolver,需要通过调用getContentResolver方法来获得
@Override
public ContentResolver getContentResolver() {
return mBase.getContentResolver();
}
该方法中调用了mBase.getContentResolver()
mBase指向的就是ContextImpl,代码执行到ContextImpl.getContentResolver
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
这个方法返回了ApplicationContentResolver类型的mContentResolver对象,ApplicationContentResolver是ContextImpl的静态内部类,继承于ContentResolver,在ContextImpl的构造方法中被创建,所以可以说当我们调用ContentResolver的insert,query,updatee等方法的时候,内容提供者就会启动
我们以ContentResolver的query方法举例,query方法在ApplicationContentResolver的父类ContentResolver中实现,query方法中主要执行了以下代码
-
通过acquireUnstableProvider方法获得IContentProvider类型的unstableProvider对象
IContentProvider unstableProvider = acquireUnstableProvider(uri);
-
调用unstableProvider的query方法
qCursor = unstableProvider.query(mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
先来到acquireUnstableProvider方法,查看其做了什么
-
判断uri的scheme是否等于content(SCHEME_CONTENT变量的值为content),如果不等于,直接return null
if (!SCHEME_CONTENT.equals(uri.getScheme())) { return null; }
-
调用acquireUnstableProvider方法,该方法是一个抽象方法,在ContentResolver的子类ApplicationContentResolver中实现,ApplicationContentResolver是ContentImpl的静态内部类
acquireUnstableProvider(mContext, uri.getAuthority());
代码运行到ContextImpl.ApplicationContentResolver.acquireUnstableProvider方法中
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), false);
}
该方法返回了ActivityThread类型的mMainThread的对象的acquireProvider方法,也就是一个IContentProvider对象,接下来来到ActivityThread.acquireProvider方法中
-
使用acquireExistingProvider方法检查ActivityThread的全局变量mProviderMap中是否包含目标内容提供者
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
-
判断provider变量是否为null,不为null就直接
return provider
如果为null就往下执行 -
调用IActivityManager的getContentProvider方法,也就是ActivityManagerService的getContentProvider方法
holder = ActivityManager.getService().getContentProvider(getApplicationThread(), auth, userId, stable);
-
调用installProvider方法来安装内容提供者,并且将getContentProvider获得的内容提供者相关数据存储在mProviderMap中,起到缓存的作用
holder = installProvider(c, holder, holder.info,true /*noisy*/, holder.noReleaseNeeded, stable);
接下来我们来到ActivityManagerService.getContentProvider方法中,该方法返回了getContentProviderImpl方法
return getContentProviderImpl(caller, name, null, stable, userId);
在ActivityManagerService.getContentProviderImpl方法中,关键部分为
-
通过getProcessRecordLocked方法来获取目标内容提供者的应用程序进程,信息通过ProcessRecord类型的proc对象来表示
ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false);
-
如果该应用程序进程已启动就执行
proc.thread.scheduleInstallProvider(cpi);
如果该应用程序进程没有启动则启动进程
proc = startProcessLocked(cpi.processName,cpr.appInfo, false, 0, "content provider", new ComponentName(cpi.applicationInfo.packageName,cpi.name), false, false, false);
我们假设应用程序进程还未启动,startProcessLocked执行的结果就是应用程序进程最后会调用ActivityThread的main方法
-
通过prepareMainLooper方法在ThreadLocal中获得Looper
Looper.prepareMainLooper();
-
开启消息循环
Looper.loop();
-
创建ActivityThread,调用其attach方法
ActivityThread thread = new ActivityThread(); thread.attach(false);
ActivityThread.attach方法主要内容如下
//获得IActivityManager
final IActivityManager mgr = ActivityManager.getService();
try {
//调用IActivityManager的attachApplication方法,并且将ApplicationThread类型的mAppThread传进去
//因为IActivityManager是ActivityManagerService的代理,最后调用的是AMS的attachApplication方法
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
AMS启动ContentProvide的过程
流程图
sequenceDiagram
调用 ->>AMS : attachApplication
activate AMS
AMS ->> AMS : attachApplicationLocked
AMS ->> IApplicationThread : bindApplication
deactivate AMS
activate IApplicationThread
IApplicationThread ->> ApplicationThread : bindApplication
deactivate IApplicationThread
activate ApplicationThread
ApplicationThread ->> ActivityThread : sendMessage
deactivate ApplicationThread
activate ActivityThread
ActivityThread ->> H : handleMessage
deactivate ActivityThread
activate H
H ->> ActivityThread : handleBindApplication
deactivate H
activate ActivityThread
ActivityThread ->> ActivityThread : installContentProviders
ActivityThread ->> ActivityThread : installProvider
ActivityThread ->> ContentProvider : attachInfo
deactivate ActivityThread
activate ContentProvider
ContentProvider ->> ContentProvider : onCreate
deactivate ContentProvider
我们查看AMS的attachApplication方法
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
该方法调用了attachApplicationLocked方法,在attachApplicationLocked方法中执行了thread.bindApplication方法
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
thread是IApplicationThread类型的,采用AIDL,bindApplication方法的实现是ApplicationThread类,是ActivityThread的内部类,ApplicationThread类定义如下
private class ApplicationThread extends IApplicationThread.Stub
ActivityThread.ApplicationThread.bindApplication方法最后调用了sendMessage方法
sendMessage(H.BIND_APPLICATION, data);
sendMessage方法向H类发送了BIND_APPLICATION类型的消息,消息会在handleMessage方法中得到处理
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
当判断到是BIND_APPLICATION类型的消息,就会执行handleBindApplication方法,该方法执行了如下逻辑
-
创建ContextImpl
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
-
通过反射创建Instrumentation
mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();
-
初始化Instrumentation
mInstrumentation.init(this, instrContext, appContext, component, data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
-
创建Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
-
调用installContentProviders方法启动ContentProvider
installContentProviders(app, data.providers);
-
调用Application的onCreate方法,意味着ContentProvider所在的应用程序已经启动
mInstrumentation.onCreate(data.instrumentationArgs);
在handleBindApplication方法中执行了installContentProviders来启动ContentProvider
-
遍历当前应用程序进程的ProviderInfo列表,得到每个ContentProvider的信息
for (ProviderInfo cpi : providers)
-
调用installProvider方法来启动这些ContentProvider
ContentProviderHolder cph = installProvider(context, null, cpi, false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
-
使用AMS的publishContentProviders方法将这些ContentProvider存储在AMS的mProviderMap中,起到缓存的作用
ActivityManager.getService().publishContentProviders(getApplicationThread(), results);
最后来到installProvider方法查看是如何启动ContentProvider的
-
通过反射来创建ContentProvider类型的localProvider对象
localProvider = (ContentProvider)cl.loadClass(info.name).newInstance();
-
调用ContentProvider的attachInfo方法
localProvider.attachInfo(c, info);
在attachInfo方法中调用了
ContentProvider.this.onCreate();
,这是一个抽象方法
到此为止,ContentProvider启动成功
四大组件启动过程总结
到此为止,学习完了四大组件的启动过程,Android8.0和Android7.0的主要区别是使用AIDL来代替了proxy代理类,四大组件启动过程都大同小异