1.Activity啓動過程 ref
從Activity的startActivity方法開始。startActivity的多個重載方法,最終都會調用startActivityForResult方法。mParent代表的是ActivityGroup,API 13之前用於在一個界面中嵌入多個Activity,之後被Fragment替代,所以這裏一般爲null。該方法中主要調用了Instrumentation#execStartActivity,其中參數mMainThread.getApplicationThread()得到的是ActivityThread的子類ApplicationThread對象,這兩個類在Activity的啓動過程中發揮了重要的作用:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
execStartActivity的關鍵代碼,即ActivityManager.getService().startActivity
。從API 26開始引入了新的ActicityManager類,替代之前舊的實現ActivityManagerNative,不過最終得到都是一個IActivityManager的單例對象,其具體實現爲ActivityManagerService(AMS)。緊隨其後的方法checkStartActivityResult,則處理了常見的找不到Intent時拋出異常的情況:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
然後來到AMS#startActivity方法,最終通過startActivityAsUser方法,調用了ActivityStartController#obtainsStarter得到一個ActivityStarter對象,執行了其execute方法。setMayWait設置了其wait標誌位爲true:
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
轉到ActivityStarter#execute方法,調用了startActivityMayWait方法(上面提到wait被置爲true),經過一翻流轉:ActivityStarter->ActivityStackSupervisor->ActivityStack->ActivityStackSupervisor,最終調用到ActivityStackSupervisor#realStartActivityLocked方法,關鍵代碼如下。與之前不同,API 28開始,通過事務的方式啓動Activity:
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
...
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
ClientLifecycleManager#scheduleTransaction,在創建ClientTransaction的時候,IApplicationThread接口的Binder對象就從Parcel中讀取出來,並指向了mClient。這裏調用了transaction的schedule方法,實際就是調用了Binder對象的scheduleTransaction方法:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
// ClientTransaction#schedule
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
而這個Binder對象遠程Binder實體,即是在最開始startActivityForResult方法中,mMainThread.getApplicationThread()得到的ActivityThread$ApplicationThread實例。其scheduleTransaction方法最終調用到ActivityThread父類的scheduleTransaction方法。舊版本中,沒有事務的概念,而是直接調用了該方法:
// ActivityThread$ApplicationThread#scheduleTransaction
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
而其scheduleTransaction的實現則非常簡單,直接發送了一個Message交由Handler處理:
// ClientTransactionHandler#scheduleTransaction
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
Handler中執行了mTransactionExecutor.execute(transaction);
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
在TransactionExecutor的excute中,調用executeCallbacks執行具體的事務ClientTransactionItem:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null) {
// No callbacks to execute, return early.
return;
}
log("Resolving callbacks");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
而這裏的ClientTransactionItem的實現類,實際爲創建事務時,傳入的LaunchActivityItem對象,其execute方法調用了client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
,這裏的client就是ActivityThread:
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
在ActivityThread的ActivityThread方法中,最終調用到了performLaunchActivity方法:
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
進入performLaunchActivity方法,開始創建Activity:
- 從ActivityClientRecord中獲取待啓動的Activity的組件信息:
ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); }
- 創建ContextImpl,通過Instrumentation#newActivity方法使用ClassLoader創建Activity對象:
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
- 通過LoadedApk#makeApplication方法嘗試創建Application對象。如果Application已經創建過了,則不會再次創建,所以一個應用只有一個Application。而創建過程同Activity也是通過Instrumentation#newApplication方法使用ClassLoader創建,創建完成後,通過callApplicationOnCreate回調Application#onCreate方法:
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
...
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
- 通過Activity#attach方法來完成重要數據的初始化,與ContextImpl的關聯,以及Window創建和與Window的關聯。
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
- 調用Activity#onCreate方法
通過mInstrumentation.callActivityOnCreate(activity, r.state);
回調Activity#onCreate。至此,Activity創建完畢。
2.Service
- 啓動過程
Activity#startService->ContextWrapper#startService,這裏的mBase,即是創建Activity時,關聯的ContextImpl對象。ContextWrapper的實現大部分由ContextImpl完成,典型的橋接模式:
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
ContextImpl#startService->startServiceCommon,同Activity,同樣會通過AMS去執行startService操作:
```
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
```
AMS#startService中調用mService的startServiceLocked方法,這個mService的類型是ActiveService,他的作用是輔助AMS進行service的啓動/綁定/停止:
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
...
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
startServiceLocked->startServiceInnerLocked,傳遞的ServiceRecord描述了一個service記錄,其一直貫穿整個service的啓動過程。然後調用bringUpServiceLocked:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
bringUpServiceLocked->realStartServiceLocked,其中主要關注兩個調用:首先同Activity,遠程調用了ApplicationThread#scheduleCreateService創建service,回調onCreate方法;然後通過sendServiceArgsLocked方法來調用其他方法,如onStartCommand方法:
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
try {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
...
sendServiceArgsLocked(r, execInFg, true);
ApplicationThread#scheduleCreateService,同Activity,也是發送Message給Handler處理:
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
Handler異步回調handleCreateService創建service:
- 通過ClassLoader創建service:
LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = packageInfo.getAppFactory() .instantiateService(cl, data.info.name, data.intent); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } }
- 創建ContextImpl,並通過service的attach方法進行關聯;視情況創建Application實例,同Activity;回調service的onCreate方法;最後,將service實例存儲到ArrayMap中:
ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService()); service.onCreate(); mServices.put(data.token, service);
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
service創建完畢,之後會被遠程調用handleServiceArgs方法,進而回調onStartCommand。
2. 綁定過程
Activity#bindService->ContextWrapper#bindService->ContextWrapper#bindServiceCommon,首先,通過LoadedApk#getServiceDispatcher方法,根據ServiceConnection得到IServiceConnection接口的Binder對象,因爲bind操作可能是跨進程,所以要使用Binder支持IPC。然後調用AMS的遠程bindService方法:
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
...
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
...
try {
...
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
獲得IServiceConnection接口Binder對象的過程:每個Context對應一個map,存儲了<ServiceConnection,LoadedApk.ServiceDispatcher>的map,通過這個ServiceDispatcher的getIServiceConnection方法,可以得到其內部類InnerConnection的實例,該類實現了IServiceConnection接口:
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
sd = map.get(c);
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}
AMS#bindService->ActiveServices#bindServiceLocked->bringUpServiceLocked->realStartServiceLocked,之後的流程同創建Service,會通過ApplicationThread來完成service創建以及onCreate方法的回調。另外,realStartServiceLocked方法中,會調用requestServiceBindingsLocked(r, execInFg)
方法,根據record執行app.thread.scheduleBindService
來進行onBind回調:
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
...
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
在ActivityThread中,同樣是通過Handler,最終執行到其handleBindService方法。回調service的onBind方法,onBind返回一個Binder對象,通過AMS#publishService將其傳遞給client,client的onServiceConnected接收到,bind操作完成:
// ApplicationThread#scheduleBindService
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
...
sendMessage(H.BIND_SERVICE, s);
}
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
client接收Binder的具體過程:AMS#publishService->ActiveServices#publishServiceLocked,其關鍵代碼c.conn.connected(r.name, service, false)
,c.conn即IServiceConnection接口,對應之前的ServiceDispatcher.InnerConnection類型:
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
進而調用ServiceDispatcher#connected。這裏的mActivityThread的類型爲Handler,他是在創建ServiceDispatcher時,傳遞進來的ActivityThread的Handler實例。所以最終會通過該Handler在主線程執行RunConnection:
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
RunConnection#run則執行了ServiceDispatcher#doConnected,client的onServiceConnected被調用:
public void doConnected(ComponentName name, IBinder service, boolean dead) {
...
// If there is a new viable service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
}
3.BroadcastReceiver
- 註冊過程
靜態註冊,同其他三大組件,在應用安裝時通過PMS(PackageManagerService)解析並註冊。
動態註冊過程如下。
ContextWrapper#registerReceiver->ContextImpl#registerReceiver->registerReceiverInternal。與bind service類似,也是先得到一個供遠程AMS調用的Binder實例,類型爲IIntentReceiver,實現類爲ReceiverDispatcher.InnerReceiver;之後調用AMS#registerReceiver方法:
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
...
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
AMS#registerReceiver關鍵代碼,將InnerReceiver遠程Binder和IntentFilter對象存儲起來:
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
...
mRegisteredReceivers.put(receiver.asBinder(), rl);
...
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {
Slog.w(TAG, "Receiver with filter " + filter
+ " already registered for pid " + rl.pid
+ ", callerPackage is " + callerPackage);
} else {
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
mReceiverResolver.addFilter(bf);
- 發送接收過程
從廣播的發送開始。
ContextWrapper#sendBroadcast->ContextImpl#sendBroadcast->AMS#broadcastIntent->AMS#broadcastIntentLocked。首先,爲其Intent中添加Intent.FLAG_EXCLUDE_STOPPED_PACKAGES
,從Android 5.0起,默認不會向已經停止的app發送廣播。如果希望向停止的app發送廣播,添加Intent.FLAG_INCLUDE_STOPPED_PACKAGES
即可,當兩個flag同時存在,以include爲準:
// By default broadcasts do not go to stopped apps.
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
之後,broadcastIntentLocked的主要工作就是,根據intent-filter查找出匹配的receiver,終將滿足的receiver添加到BroadcastRecord中,接着執行scheduleBroadcastsLocked方法發送廣播:
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
...
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, false, userId);
...
if (!replaced) {
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
...
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
...
} else {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
BroadcastQueue#scheduleBroadcastsLocked只是發出一個message:
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
之後,Handler調用processNextBroadcast->processNextBroadcastLocked。以無序廣播爲例,取出BroadcastRecord,遍歷其中的receiver,調用deliverToRegisteredReceiverLocked方法向target發出廣播:
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
...
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering non-ordered on [" + mQueueName + "] to registered "
+ target + ": " + r);
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
deliverToRegisteredReceiverLocked->performReceiveLocked,最終調用了app.thread.scheduleRegisteredReceiver,回到了ApplicationThread:
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
ApplicationThread#scheduleRegisteredReceiver->IIntentReceiver.performReceive,IIntentReceiver即爲註冊receiver時,創建的Binder對象實例,類型爲ReceiverDispatcher.InnerReceiver:
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
InnerReceiver#performReceive->ReceiverDispatcher#performReceive,該方法中,通過
創建一個Runnable,將調用onReceive的操作,交給mActivityThread即Handler去執行,該Handler就是ActivityThread中的H:
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
...
if (intent == null || !mActivityThread.post(args.getRunnable())) {
最終,onReceive在主線程中被調用:
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
4.ContentProvider
應用啓動流程:
- VM調用ActivityThread的main方法。
- main方法中,會創建ActivityThread的實例,然後調用其attach方法;同時會創建主線程的消息隊列。
- attch方法中,會調用AMS的遠程方法attachApplication,將其ApplicationThread傳遞給AMS。ApplicationThread是個Binder對象,用於ActivityThread和AMS的通信。
- 在AMS的attachApplication方法中,會遠程調用ApplicationThread的bindApplication方法,ApplicationThread轉而交由ActivityThread的Handler處理,具體方法爲handleBindApplication。
- 在handleBindApplication方法中,會創建Application對象,並加載ContentProvider。加載過程發生在回調Application的onCreate方法之前。
ContentProvider可以通過android:multiProcess
來爲其指定多實例,在每個調用者的進程中,都存在一個CopntentProvider實例。不過大部分的使用場景,ContentProvider爲單實例。
訪問ContentProvider使用的ContentResolver是個抽象類,getContentResolver得到的實例實際爲ContextImpl.ApplicationContentResolver。當通過其四個方法訪問ContentProvider時,其所在進程未啓動,則會觸發其創建,並伴隨着ContentProvider的創建。這裏以query爲例。
ContentResolver#query首先調用了acquireUnstableProvider方法,來獲取一個IContentProvider實例。然後調用了子類的acquireUnstableProvider方法,這裏的mMainThread即是ActivityThread:
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), false);
}
ActivityThread#acquireProvider,首先會判斷目標provider是否存在,如果存在直接返回;如果不存在則通過AMS#getContentProvider方法去創建他,最後通過installProvider修改引用計數:
public final IContentProvider acquireProvider(
Context c, String auth, int userId, boolean stable) {
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
...
try {
synchronized (getGetProviderLock(auth, userId)) {
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
...
// Install provider will increment the reference count for us, and break
// any ties in the race.
holder = installProvider(c, holder, holder.info,
true /*noisy*/, holder.noReleaseNeeded, stable);
return holder.provider;
}
AMS#getContentProvider->AMS#getContentProviderImpl->startProcessLocked->startProcess,首先創建目標進程。具體爲調用了Process.start方法:
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
...
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
新進程啓動後,其入口方法爲ActivityThread#main:
public static void main(String[] args) {
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
如前述,Activity#attach->AMS#attachApplication->AMS#attachApplicationImpl->ApplicationThread#bindApplication,然後交由ActivityThread的Handler處理,具體在handleBindApplication方法:
首先,創建ContextImpl和Instrumentation:
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
創建Application:
Application app;
...
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
mInitialApplication = app;
創建ContentProvider,並調用其onCreate方法。
- installContentProviders方法中,遍歷當前進程的ProviderInfo列表,一一調用其installProvider方法來啓動他們。然後將ContentProvider發佈到AMS當中,AMS會把其存儲在ProviderMap中,下次調用便可直接獲得provider實例:
installContentProviders(app, data.providers);
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
if (DEBUG_PROVIDER) {
StringBuilder buf = new StringBuilder(128);
buf.append("Pub ");
buf.append(cpi.authority);
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
}
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
- provider的具體創建過程在installProvider方法中完成。通過ClassLoader創建provider對象,然後調用其attachInfo回調onCreate方法:
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
...
try {
final java.lang.ClassLoader cl = c.getClassLoader();
LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);
if (packageInfo == null) {
// System startup case.
packageInfo = getSystemContext().mPackageInfo;
}
localProvider = packageInfo.getAppFactory()
.instantiateProvider(cl, info.name);
...
localProvider.attachInfo(c, info);
provider創建完成,調用Application的onCreate方法:
try {
mInstrumentation.callApplicationOnCreate(app);
至此,ContentProvider創建完成,其進程的Application也創建完成。使用ContentProvider時,實際上是通過獲得的IContentProvider接口去執行遠程調用,實際類型爲ContentProvider.Transport,其query方法:
@Override
public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
...
try {
return ContentProvider.this.query(
uri, projection, queryArgs,
CancellationSignal.fromTransport(cancellationSignal));
調用ContentProvider的query方法,然後通過Binder傳遞給client,完成了一次調用,其他方法類似。