在Activity启动流程(3)中,Launcher已经执行了onPause方法,并告知了ActivityManagerService,本篇就分析下ActivityManagerService收到Launcher的通知后会执行的操作。
ActivityManagerService类activityPaused
public final void activityPaused(IBinder token) {
......
mMainStack.activityPaused(token, false);
......
}
ActivityStack类activityPaused
很简单,主要就是调用了ActivityStack的activityPaused方法,其中token指向的之Launcher的ActivityRecord。
inal void activityPaused(IBinder token, boolean timeout) {
ActivityRecord r = null;
synchronized (mService) {
int index = indexOfTokenLocked(token);
if (index >= 0) {
r = mHistory.get(index);
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
r.state = ActivityState.PAUSED;
completePauseLocked();
} else {
......
}
}
}
}
由于此时mPausingActivity与Launcher相同,故completePauseLocked
会被执行。
ActivityStack类completePauseLocked
private final void completePauseLocked() {
ActivityRecord prev = mPausingActivity;
......
if (prev != null) {
if (prev.finishing) {
......
} else if (prev.app != null) {
.....
if (prev.configDestroy) {
......
} else {
mStoppingActivities.add(prev);
......
} else {
......
}
}
} else {
......
}
mPausingActivity = null;
}
if (!mService.isSleeping()) {
resumeTopActivityLocked(prev);
} else {
......
}
......
}
由于隐藏了无关和启动流程无关的代码,故流程已经很清晰了,prev
指向的正是Launcher的ActivityRecord。接下来resumeTopActivity
会被执行。
ActivityStack类resumeTopActivity
final boolean resumeTopActivityLocked(ActivityRecord prev) {
// Find the first activity that is not finishing.
ActivityRecord next = topRunningActivityLocked(null);
// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mUserLeaving;
mUserLeaving = false;
if (next == null) {
......
}
next.delayedResume = false;
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
......
}
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
if ((mService.mSleeping || mService.mShuttingDown)
......
}
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
......
if (mPausingActivity != null) {
......
}
if (false) {
......
}
// We need to start pausing the current activity so the top one
// can be resumed...
if (mResumedActivity != null) {
......
}
if (prev != null && prev != next) {
if (!prev.waitingVisible && next != null && !next.nowVisible) {
......
} else {
......
} else {
......
}
}
}
// Launching this app's activity, make sure the app is no longer
// considered stopped.
......
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
if (prev != null) {
if (prev.finishing) {
......
}
if (false) {
......
}
} else if (mHistory.size() > 1) {
......
}
if (next.app != null && next.app.thread != null) {
......
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
......
startSpecificActivityLocked(next, true, true);
}
return true;
}
要理解这段代码,需要知道目前Launcher和目标Activity的状态。执行到这段代码时,Launcher已经处于结束了onPause方法的执行,正处于paused的状态,目前处于最Activity栈 栈顶的Activity为目标Activity,但是此时目标Activity的实例还未被初始化,目标Activity所在应用的进程也未被新建。next指向的就是目标Activity,prev指向的是Launcher,next.app指向目标Activity所在的进程,由于此时应用进程未被创建,故next.app = null,将会执行startSpecificActivityLocked(next, true, true)
ActivityStack类startSpecificActivityLocked
private final 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);
......
if (app != null && app.thread != null) {
......
}
// 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);
}
由于应用程序为启动,故app = null,接下来会执行startProcessLocked
ActivityManagerService类startProcessLocked
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
ProcessRecord app = getProcessRecordLocked(processName, info.uid);
......
if (app != null && app.pid > 0) {
//代码块1
......
}
String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;
if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
//代码块2
......
}
} else {
......
}
}
if (app == null) {
//代码块3
app = newProcessRecordLocked(null, info, processName);
mProcessNames.put(processName, info.uid, app);
} else {
......
}
// If the system is not ready yet, then hold off on starting this
// process until it is.
if (!mProcessesReady
&& !isAllowedWhileBooting(info)
&& !allowWhileBooting) {
......
}
startProcessLocked(app, hostingType, hostingNameStr);
return (app.pid != 0) ? app : null;
}
进入该函数执行时,目标Activity还没有执行onCreate方法,目标Activity所在的进程也没有被创建,故app = null;intentFlags = 0,故代码块2不会被执行,app = null,故代码块3也不会被执行,最终函数的调用会走到startProcessLocked
的重载方法中,app是调用newProcessRecordLocked
方法后返回的一个进程实例,hostingType=”Activity”,hostingNameStr是目标Activity的全限定名,如com.example.Activity1
ActivityManagerService类startProcessLocked
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
if (app.pid > 0 && app.pid != MY_PID) {
......
}
......
try {
int uid = app.info.uid;
int[] gids = null;
try {
gids = mContext.getPackageManager().getPackageGids(
app.info.packageName);
} catch (PackageManager.NameNotFoundException e) {
Slog.w(TAG, "Unable to retrieve gids", e);
}
if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
&& mTopComponent != null
&& app.processName.equals(mTopComponent.getPackageName())) {
uid = 0;
}
if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
&& (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
uid = 0;
}
}
int debugFlags = 0;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
// Also turn on CheckJNI for debuggable apps. It's quite
// awkward to turn on otherwise.
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
// Run the app in safe mode if its manifest requests so or the
// system is booted in safe mode.
if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
Zygote.systemInSafeMode == true) {
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
}
if ("1".equals(SystemProperties.get("debug.assert"))) {
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags,
app.info.targetSdkVersion, null);
......
}
去掉了不影响流程的代码,代码的流程就显得很清晰。这部分代码的主要工作就是收集目标Activity所在包的gid信息,设置调试标识debugFlags,然后去启动android.app.ActivityThread
类,并调用ActivityThread的main方法。
ActivityThread表示应用的UI线程,也就是主线程,看下main方法里面做了什么操作。
ActivityThread类main
public static void main(String[] args) {
......
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
好吧,为什么我们可以在Activity里面随意new Handler
,这下就很明白了,main方法的逻辑很简单,就是新建了消息队列,并开始了Looper循环。下一步要看得函数就是thread.attach(false)
ActivityThread类attach
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
//代码块1
......
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
//代码块2
......
}
......
}
由于应用不是系统应用,故代码块1会被执行,而代码块2不会被执行。代码块2是Binder夸进程调用,故调用最终会转移到ActivityManangerService
中,到ActivityManangerService
找下attachApplication
方法的实现。
ActivityManagerService类attachApplication
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
......
attachApplicationLocked(thread, callingPid);
......
}
}
调用又到了attachApplicationLocked
方法,thread代表已经启动的应用进程,callPid代表已经启动的进程的pid,这里已经启动的进程是指目标Activity所在的进程。
ActivityManagerService类attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
if (app == null) {
......
return false;
}
// If this application record is still attached to a previous
// process, clean it up now.
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
// Tell the process all about itself.
if (localLOGV) Slog.v(
TAG, "Binding process pid " + pid + " to record " + app);
String processName = app.processName;
......
app.thread = thread;
app.curAdj = app.setAdj = -100;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.forcingToForeground = null;
app.foregroundServices = false;
app.hasShownUi = false;
app.debugging = false;
......
boolean badApp = false;
boolean didSomething = false;
......
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
badApp = true;
}
} else {
......
}
}
......
}
代码执行到这里时,目标Activity所在应用的Process已经新建完成,这部分的主要功能是取出已经新建的Process并对Process的属性进行设置。最后调用mMainStack.topRunningActivityLocked(null)
方法获取当前在栈顶的Activity的对象ActivityRecord,执行mMainStack.realStartActivityLocked(hr, app, true, true)
方法去启动目标Activity。
ActivityStack类realStartActivity
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
......
try {
if (app.thread == null) {
throw new RemoteException();
}
List<ResultInfo> results = null;
List<Intent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}
......
r.sleeping = false;
r.forceNewConfig = false;
showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
String profileFile = null;
ParcelFileDescriptor profileFd = null;
boolean profileAutoStop = false;
if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
......
}
app.hasShownUi = true;
app.pendingUiClean = true;
......
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
System.identityHashCode(r), r.info, mService.mConfiguration,
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
......
}
这段代码最终调用app.thread.scheduleLaunchActivity
,这个调用是夸进程调用,最终的调用会在ActivityThread.ApplicationThread.scheduleLaunchActivity
执行。
ActivityThread.Application类scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
又看到了queueOrSendMessage
方法,没有印象的亲可以朝前看。看下这里的H
为Handler类型,看下handleMessage
的函数处理逻辑。
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
} break;
函数的调用又转到了handleLaunchActivity
。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity a = performLaunchActivity(r, customIntent);
......
}
哈哈,到这里感觉马上就要看到Activity的onCreate函数了,去看看performLaunchActivity
。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
......
ComponentName component = r.intent.getComponent();
......
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} 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) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);
......
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
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;
}
哎呀我去,终于看到了callActivityOnCreate,终于到Activity开始执行onCreate方法了。好了,这部分的流程算是看完了,接下来我会总结下Activity的启动流程。