个人博客

http://www.milovetingting.cn

四大组件的工作过程

四大组件:Activity、Service、BroadcastReceiver、ContentProvider

四大组件的运行状态

Android的四大组件中除了BroadcastReceiver,其它三种组件必须在AndroidManifest中注册。对于BroadcastReceiver,既可以在AndroidManifest中注册,也可以通过代码注册。调用方式上,Activity、Service和BroadcastReceiver都需要借助Intent,而ContentProvider则不需要。

Activity是一种展示型组件。Activity的启动由Intent触发,Intent可以分为显示Intent和隐式Intent。

Service是一种计算型组件,它有两种状态:启动状态和绑定状态。Service虽然是运行在后台,但它本身是运行在主线程中。

BroadcastReceiver是一种消息型组件。它的注册有两种:静态注册和动态注册。

ContentProvider是一种数据共享型组件。它的内部需要实现增删改查这四种操作。这四个方法需要处理好线程同步。

Activity的工作过程

从Activity的startActivity方法开始分析,startActivity方法有几个重载,但最终都会调用startActivityForResult方法

public void startActivity(Intent intent) {
this.startActivity(intent, null);
} public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

startActivityForResult方法实现如下:

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());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
} cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}

在mParent == null的分支里,会调用Instrumentation的execStartActivity方法

public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
//...
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);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

可以看到,ActivityManager.getService()是一个单例,返回的是一个Binder对象。

public static IActivityManager getService() {
return IActivityManagerSingleton.get();
} private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};

最终启动Activity是由ActivityManagerService的startActivity方法实现。

public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
} 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) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}

Activity的启动转移到了ActivityStarter的startActivityMayWait方法里

final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
TaskRecord inTask, String reason) {
//...
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
//...
}
}

startActivityMayWait方法会调用startActivityLocked方法

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason) { //...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask);
//...
}

在startActivityLocked方法里调用了startActivity方法,startActivity方法内又调用doPendingActivityLaunchesLocked方法

final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
null, null /*outRecords*/);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
} private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
} postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
mTargetStack); return result;
}

startActivity调用startActivityUnchecked方法

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) { //...
if (dontStart) {
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
//...
} //...
}

startActivityUnchecked调用ActivityStackSupervisor中的resumeFocusedStackTopActivityLocked方法

boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
} boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (!readyToResume()) {
return false;
} if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
} return false;
}

resumeFocusedStackTopActivityLocked调用了ActivityStack的resumeTopActivityUncheckedLocked方法

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
} boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
} // When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
// We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
// any necessary pause logic occurs. In the case where the Activity will be shown regardless
// of the lock screen, the call to {@link ActivityStackSupervisor#checkReadyForSleepLocked}
// is skipped.
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
} return result;
}

resumeTopActivityInnerLocked方法最终调用ActivityStackSupervisor中的startSpecificActivityLocked方法

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
//...
}

resumeTopActivityInnerLocked方法调用realStartActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true); r.getStack().setLaunchTime(r); if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
} // If a dead object exception was thrown -- fall through to
// restart the application.
} mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}

在realStartActivityLocked方法中,通过ProcessRecord的thread来启动Activity。而thread是一个IApplicationThread类型的对象,它的具体实现为ActivityThread中的内部类ApplicationThread。

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
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, !andResume,
mService.isNextTransitionForward(), profilerInfo); //...
}
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState; r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed;
r.isForward = isForward; r.profilerInfo = profilerInfo; r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r);
}

到这里,Activity的启动已经转到了ApplicationThread中。在scheduleLaunchActivity方法中,发了一个启动的消息LAUNCH_ACTIVITY出去。

public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
//...
}
//...
}

在Handler中,调用了ActivityThread的handleLaunchActivity方法

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//...
WindowManagerGlobal.initialize(); Activity a = performLaunchActivity(r, customIntent); if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); if (!r.activity.mFinished && r.startsNotResumed) {
// The activity manager actually wants this one to start out paused, because it
// needs to be visible but isn't in the foreground. We accomplish this by going
// through the normal startup (because activities expect to go through onResume()
// the first time they run, before their window is displayed), and then pausing it.
// However, in this case we do -not- need to do the full pause cycle (of freezing
// and such) because the activity manager assumes it can just retain the current
// state it has.
performPauseActivityIfNeeded(r, reason); // We need to keep around the original state, in case we need to be created again.
// But we only do this for pre-Honeycomb apps, which always save their state when
// pausing, so we can not have them save their state when restarting from a paused
// state. For HC and later, we want to (and can) let the state be saved as the
// normal part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}

在performLaunchActivity方法中,完成了Activity对象的创建和启动过程。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//...
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
} try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation); //... if (activity != null) {
//...
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
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); //...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true; mActivities.put(r.token, r); } catch (SuperNotCalledException e) {
throw e; } catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
} return activity;
}

Activity启动时序图

Service的工作过程

Service的启动过程

Service的启动是从ContextWrapper的startService开始

public ComponentName startService(Intent service) {
return mBase.startService(service);
}

mBase的具体类型是ContextImpl,Activity创建时会通过attach将一个ContextImpl对象关联起来。startService方法会调用startServiceCommon方法。

public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}

startServiceCommon对象会调用ActivityManagerService的startService方法,这是一个远程调用的过程。

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
//...
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
//...
}

ActivityManagerService的startService方法

public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
//...
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
//...
}

startService方法会调用ActiveServices的startServiceLocked方法

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
//...
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}

在startServiceLocked方法里会调用startServiceInnerLocked方法

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
//...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
//...
}

startServiceInnerLocked里调用了bringUpServiceLocked方法

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//...
realStartServiceLocked(r, app, execInFg);
//...
}

bringUpServiceLocked里调用realStartServiceLocked方法

private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//...
//创建Service
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
//...
//调用Service的start方法
sendServiceArgsLocked(r, execInFg, true);
//...
}

realStartServiceLocked调用ApplicationThread中的scheduleCreateService方法

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);
}

在scheduleCreateService方法里,发了一个创建服务的消息出去。Handler处理CREATE_SERVICE的消息,并通过ActivityThread的handleCreateService方法来完成Service的启动。

private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
} try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 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);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}

Service启动的时序图

Service的绑定过程

Service的绑定是从ContextWrapper的bindService方法开始的

public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}

然后调用ContextImpl的bindService方法

public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}

bindService调用bindServiceCommon方法

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
//...
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
//...
}

bindServiceCommon调用ActivityManagerService的bindService方法

public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
//...
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}

bindService调用ActiveServices中的bindServiceLocked方法

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
//...
bringUpServiceLocked(serviceRecord,serviceIntent.getFlags(),callerFg, false, false);
//...
}

bindServiceLocked调用bringUpServiceLocked方法

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//...
realStartServiceLocked(r, app, execInFg);
//...
}

bringUpServiceLocked调用realStartServiceLocked方法。这个过程和之前的启动过程已经是一样的。不同的是,Service绑定过程还会调用ApplicationThread的scheduleBindService方法,这个过程是在ActiveServices的requestServiceBindingLocked方法中

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
+ " rebind=" + rebind);
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);
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
} catch (TransactionTooLargeException e) {
// Keep the executeNesting count accurate.
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
} catch (RemoteException e) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
}
}
return true;
}
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind; if (DEBUG_SERVICE)
Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
+ Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
sendMessage(H.BIND_SERVICE, s);
}

在scheduleBindService方法里,发送一个绑定服务的消息。在ActivityThread里调用handleBindService方法

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);
}
ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}

服务的绑定时序图:

BroadcastReceiver的工作过程

广播的注册过程

广播的注册分为静态注册和动态注册,其中静态注册的广播在应用安装时由系统自动完成注册。这里只分析广播的动态注册过程。动态注册是从ContextWrapper的registerReceiver方法开始的

public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}

registerReceiver调用ContextImpl中的registerReceiver方法

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}

registerReceiver再调用内部的registerReceiver方法

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext(), 0);
}

registerReceiver会调用registerReceiverInternal方法

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
//...
try {
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();
}
}

registerReceiverInternal调用了AMS的registerReceiver方法

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
//...
synchronized (this) {
//...
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
mReceiverResolver.addFilter(bf);
//...
return sticky;
}
}

广播的发送和接收过程

广播的发送是通过ContextWrapper的sendBroadcast方法实现的

public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}

sendBroadcast调用了ContextImpl中的sendBroadcast方法

public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

sendBroadcast调用了AMS的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();
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;
}
}

broadcastIntent调用broadcastIntentLocked方法

final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
//...
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
//...
}

broadcastIntentLocked调用了BroadcastQueue的enqueueOrderedBroadcastLocked将广播添加到队列中,通过BroadcastQueue的scheduleBroadcastsLocked来处理队列中的广播。

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;
}

在scheduleBroadcastsLocked方法中,通过Handler发送了一个BROADCAST_INTENT_MSG的消息

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;
}
}

在Handler的handleMessage方法中处理消息,调用了processNextBroadcast方法

final void processNextBroadcast(boolean fromMsg) {
//...
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
//...
}

processNextBroadcast方法调用deliverToRegisteredReceiverLocked

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
//...
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
//...
}

deliverToRegisteredReceiverLocked调用performReceiveLocked

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);
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
// DeadObjectException when the process isn't actually dead.
//} catch (DeadObjectException ex) {
// Failed to call into the process. It's dying so just let it die and move on.
// throw ex;
} catch (RemoteException ex) {
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.pid + "). Crashing it.");
app.scheduleCrash("can't deliver broadcast");
}
throw ex;
}
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}

performReceiveLocked调用ApplicationThread的scheduleRegisteredReceiver方法

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);
}

scheduleRegisteredReceiver里调用LoadedApk的内部类ReceiverDispatcher中的performReceive方法

public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
Log.wtf("LoadedApk", "Null intent received");
rd = null;
} else {
rd = (LoadedApk.ReceiverDispatcher)this.mDispatcher.get();
} if (rd != null) {
rd.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);
} else {
IActivityManager mgr = ActivityManagerNative.getDefault(); try {
if (extras != null) {
extras.setAllowFds(false);
} mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException var11) {
throw var11.rethrowFromSystemServer();
}
} }

performReceive调用performReceive的重载

public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher.Args args = new LoadedApk.ReceiverDispatcher.Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);
if (intent == null) {
Log.wtf("LoadedApk", "Null intent received");
} if ((intent == null || !this.mActivityThread.post(args)) && this.mRegistered && ordered) {
IActivityManager mgr = ActivityManagerNative.getDefault();
args.sendFinished(mgr);
} }

performReceive调用ActivityThread的内部类Handler的post方法,将Args发送出去,Args是一个Runnable接口,在Handler处理消息时,会回调Args的run方法

public void run() {
//...
receiver.onReceive(ReceiverDispatcher.this.mContext, intent);
//...
}

在run中回调receiver的onReceiver方法

广播注册的时序图

广播发送及接收的时序图

ContentProvider的工作过程

当ContentProvider所在的进程启动时,ContentProvider会同时启动并被发布到AMS中,这个时候ContentProvider的onCreate要先于Application的onCreate执行。

应用启动时的入口为ActivityThread的main方法

public static void main(String[] args) {
//...
Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread();
thread.attach(false); 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");
}

在main方法中,会创建ActivityThread的实例,并调用attach方法,然后调用Looper.loop方法。这里主要分析attach方法。

private void attach(boolean system) {
//...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//...
}

在attach中,调用AMS的attachApplication方法

public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}

attachApplication调用attachApplicationLocked方法

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
//...
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
//...
}

attachApplicationLocked调用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 enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) { if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
} setCoreSettings(coreSettings); AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
sendMessage(H.BIND_APPLICATION, data);
}

bindApplication发送消息BIND_APPLICATION给Handler

public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
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;
//...
}
}

handleMessage中调用ActivityThread中的handleBindApplication方法

private void handleBindApplication(AppBindData data) {
//...
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
//...
mInstrumentation.callApplicationOnCreate(app);
//...
}

handleBindApplication中创建了application实例和ContentProvider,并且Application的onCreate回调在ContentProvider之后。

下面来看installContentProviders方法

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());
}
//1
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
} try {
//2
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}

在注释1处调用installProvider方法。注释2处调用AMS的publishContentProviders方法

private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
//...
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " +
info.name + " from sourceDir " +
info.applicationInfo.sourceDir);
return null;
}
if (DEBUG_PROVIDER) Slog.v(
TAG, "Instantiating local provider " + info.name);
// XXX Need to create the correct context for this provider.
localProvider.attachInfo(c, info);
//...
}

在installProvider创建了provider,并调用了attachInfo方法

private void attachInfo(Context context, ProviderInfo info, boolean testing) {
mNoPerms = testing; /*
* Only allow it to be set once, so after the content service gives
* this to us clients can't change it.
*/
if (mContext == null) {
mContext = context;
if (context != null) {
mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
Context.APP_OPS_SERVICE);
}
mMyUid = Process.myUid();
if (info != null) {
setReadPermission(info.readPermission);
setWritePermission(info.writePermission);
setPathPermissions(info.pathPermissions);
mExported = info.exported;
mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;
setAuthorities(info.authority);
}
ContentProvider.this.onCreate();
}
}

在attchInfo中调用了onCreate方法

再看AMS的publishContentProviders方法

public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
//...
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}
//...
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
//...
}

在publishContentProviders方法中,主要是将provider信息保存到Map中,移除CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息。因为在AMS的attachApplicationLocked方法中发送了一个CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息,以便在超时的时候作出相应的处理。

ContentProvider的启动时序图

访问ContentProvider需要通过ContentResolver,ContentResolver是一个抽象类,通过Context获取到的ContentResolver,其实是ContextImpl中的内部类ApplicationContentResolver的一个实例。当ContentProvider所在进程未启动时,第一次访问它就会触发ContentProvider的创建,ContentProvider的进程也会启动。通过ContentProvider的增删改查的任何一个方法都会触发ContentProvider的启动。这里选择query方法来分析。

ContentProvider的使用方法一般是如下这样:

context.getContentResolver().query()

context的实现类是ContextWrapper.来看ContextWrapper的getContentResolver方法

public ContentResolver getContentResolver() {
return mBase.getContentResolver();
}

getContentResolver调用ContextImpl的getContentResolver方法

public ContentResolver getContentResolver() {
return mContentResolver;
}

mContentResolver是在ContextImpl的构造函数中初始化的

private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) {
//...
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
//...
}

ApplicationContentResolver是ContextImpl的内部类。实例化ContentResolver后,调用query方法

public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
//...
IContentProvider unstableProvider = acquireUnstableProvider(uri);
//...
}

在query方法里,先通过acquireUnstableProvider获取ContentProvider

public final IContentProvider acquireUnstableProvider(Uri uri) {
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
String auth = uri.getAuthority();
if (auth != null) {
return acquireUnstableProvider(mContext, uri.getAuthority());
}
return null;
}

acquireUnstableProvider会调用它的重载方法acquireUnstableProvider

protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return this.mMainThread.acquireProvider(c, ContentProvider.getAuthorityWithoutUserId(auth), this.resolveUserIdFromAuthority(auth), false);
}

acquireUnstableProvider方法会调用ActivityThread的acquireProvider方法

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;
} // There is a possible race here. Another thread may try to acquire
// the same provider at the same time. When this happens, we want to ensure
// that the first one wins.
// Note that we cannot hold the lock while acquiring and installing the
// provider since it might take a long time to run and it could also potentially
// be re-entrant in the case where the provider is in the same process.
ContentProviderHolder holder = null;
try {
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth);
return null;
} // 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;
}

如果有缓存过ContentProvider,则直接获取返回。如果没有缓存,则通过AMS的getContentProvider方法获取

public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String name, int userId, boolean stable) {
enforceNotIsolatedCaller("getContentProvider");
if (caller == null) {
String msg = "null IApplicationThread when getting content provider "
+ name;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
// The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
// with cross-user grant.
return getContentProviderImpl(caller, name, null, stable, userId);
}

ContentProviderHolder调用getContentProviderImpl方法获取ContentResoverHolder

获取到Provider后,就会调用ContentProvider的query方法,这个方法是我们自定义ContentProvider时需要实现的。代码就切换到了我们定义的ContentProvider。

ContentProvider的Query时序图

【Android开发艺术探索】四大组件的工作过程的更多相关文章

  1. 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程

    第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...

  2. 《android开发艺术探索》读书笔记(九)--四大组件

    接上篇<android开发艺术探索>读书笔记(八)--WindowManager No1: 四大组件除了BroadcastReceiver,其他三种组件都必须在AndroidManifes ...

  3. 《android开发艺术探索》读书笔记(四)--View工作原理

    接上篇<android开发艺术探索>读书笔记(三) No1: View的三大流程:测量流程.布局流程.绘制流程 No2: ViewRoot对应于ViewRootImpl类,它是连接Wind ...

  4. 《android开发艺术探索》读书笔记(十一)--Android的线程和线程池

    接上篇<android开发艺术探索>读书笔记(十)--Android的消息机制 No1: 在Android中可以扮演线程角色的有很多,比如AsyncTask.IntentService.H ...

  5. 《android开发艺术探索》读书笔记(十)--Android的消息机制

    接上篇<android开发艺术探索>读书笔记(九)--四大组件 No1: 消息队列MessageQueue的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表,因为单链表 ...

  6. 《android开发艺术探索》读书笔记(二)--IPC机制

    接上篇<android开发艺术探索>读书笔记(一) No1: 在android中使用多进程只有一种方法,那就是给四大组件在AndroidMenifest中指定android:process ...

  7. Android开发艺术探索——第二章:IPC机制(上)

    Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...

  8. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  9. Android开发艺术探索——新的征程,程序人生路漫漫!

    Android开发艺术探索--新的征程,程序人生路漫漫! 偶尔写点东西分享,但是我还是比较喜欢写笔记,看书,群英传看完了,是学到了点东西,开始看这本更加深入Android的书籍了,不知道适不适合自己, ...

随机推荐

  1. 个人任务day5

    今日计划: 写登录界面,学习如何使用js做出界面跳转的进度条动态显示. 昨日成果: 创建用户数据库.

  2. Java程序员学习Go指南(二)

    摘抄:https://www.luozhiyun.com/archives/211 Go中的结构体 构建结构体 如下: type AnimalCategory struct { kingdom str ...

  3. C语言寒假大作战01

    问题 回答 这个作业属于哪个课程 2019软件四班C语言寒假作业大作战 这个作业要求在哪里 作业要求 我在这个课程的目标是 gitee 与 git基础命令学习与使用 这个作业在那个具体方面帮助我实现目 ...

  4. K8S生产环境中实践高可靠的配置和技巧都有哪些?

    K8S环境中实践高可靠的配置和技巧都有哪些? 磁盘类型及大小 磁盘类型: 推荐使用ssd 磁盘 对于worker节点,创建集群时推荐使用挂载数据盘.这个盘是专门给/var/lib/docker 存放本 ...

  5. git hub安装

    windows下GitHub的安装.配置以及项目的上传过程详细介绍 阅读目录 概要 操作必备 GitHub的安装 Git的初始配置 本地Git与远程GitHub连接的建立 将本地项目上传到GitHub ...

  6. Linux中软件安装包的格式

    一.Linux常用安装包及安装方法 1.安装包一般有四类: 1)tar包,如software-1.2.3-1.tar.gz.他是使用UNIX系统的打包工具tar打包的. 2)rpm包,如softwar ...

  7. hash算法与拉链法解决冲突

    <?php class HashNode { public $key; public $value; public $nextNode; public function __construct( ...

  8. JS中for...in循环陷阱及遍历数组的方式对比

    JavaScript中有很多遍历数组的方式,比较常见的是for(var i=0;i<arr.length;i++){},以及for...in...循环等,这些遍历都有各自的优缺点,下面来看看各种 ...

  9. Shiro身份验证及授权(二)

    一.Shiro 身份验证 身份验证的步骤: 收集用户身份 / 凭证,即如用户名 / 密码: 调用 Subject.login 进行登录,如果失败将得到相应的 AuthenticationExcepti ...

  10. iNeuOS工业互联平台,iNeuKernel(物联网核心组件)远程控制标准化设计与实现。发布v2.3版本。

    目       录 1.      概述... 2 2.      平台演示... 2 3.      控制端与iNeuKernel的交互协议... 3 4.      设备驱动实现控制业务... 4 ...