Activity工作流程
Posted 爱搬砖的摄影师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity工作流程相关的知识,希望对你有一定的参考价值。
从startActivity
/startActivityForResult
开始,不管是哪种方式,最终调到的都是下面的startActivityForResult
。
// Activity
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options)
// mParent一般都是null,这个变量是ActivityGroup,用来在一个页面
// 嵌入多个子页面,在API13中废弃,推荐使用Fragment代替。
if (mParent == null)
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的情况。主要过程很简单,首先启动Activity并且得到结果,然后返回执行结果。
// Instrumentation
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options)
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try
...
int result = ActivityManagerNative.getDefault()
.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;
实际的startActivity通过ActivityManagerNative.getDefault()
返回的东西来完成。看看这个返回的是什么。
// ActivityManagerNative
static public IActivityManager getDefault()
return gDefault.get();
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
protected IActivityManager create()
IBinder b = ServiceManager.getService("activity");
if (false)
Log.v("ActivityManager", "default service binder = " + b);
IActivityManager am = asInterface(b);
if (false)
Log.v("ActivityManager", "default service = " + am);
return am;
;
public abstract class Singleton<T>
private T mInstance;
protected abstract T create();
public final T get()
synchronized (this)
if (mInstance == null)
mInstance = create();
return mInstance;
通过上面两段代码可以发现,ActivityManagerNative.getDefault()
得到的实际上是一个单例的IActivityManager
,更准确地说,是一个ActivityManagerService实例。在看AMS的startActivity之前,先来看看,checkStartActivityResult(result, intent);
是干嘛的。
// Instrumentation
public static void checkStartActivityResult(int res, Object intent)
if (res >= ActivityManager.START_SUCCESS)
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);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case ActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
case ActivityManager.START_NOT_VOICE_COMPATIBLE:
throw new SecurityException(
"Starting under voice control not allowed for: " + intent);
case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
// Fail silently for this case so we don't break current apps.
// TODO(b/22929608): Instead of failing silently or throwing an exception,
// we should properly position the activity in the stack (i.e. behind all current
// user activity/task) and not change the positioning of stacks.
Log.e(TAG,
"Not allowed to start background user activity that shouldn't be displayed"
+ " for all users. Failing silently...");
break;
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
这段代码非常清楚,就是为了检测AMS中startActicity的结果,如果没有成功启动,就会抛出相应的异常信息。
再看AMS的startActivity。
// ActivityManagerService
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options)
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
现在启动Activity的过程来到了ActivityStackSupervisor类。简单看看startActivityMayWait方法。
// ActivityStackSupervisor
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 config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask)
...
// resolveActivity解析intent,找到intent对应Activity的
// ActivityInfo信息,实际是由PackageManagerService完成的。
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
...
final ActivityStack stack;
// container为null,获取到当前正在前台的栈
if (container == null || container.mStack.isOnHomeDisplay())
stack = mFocusedStack;
else
stack = container.mStack;
...
// 尽管aInfo不为null,但是该属性一般没设置,所以不会走进这个逻辑
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0)
...
// 启动Activity流程走到这个方法里
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
...
来看startActivityLocked方法。
// ActivityStackSupervisor
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask)
...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
...
再简单看看startActivityUncheckedLocked,singleTask等启动模式就是在这个方法里处理的,这里不对其进行分析,之后另开一篇专门分析这个。
// ActivityStackSupervisor
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask)
...
// 启动模式相关,这里不深入分析
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
...
// 该属性表示非用户操作,一般不设置,所以mUserLeaving为true,
// 这样Activity暂停之前就会调用onUserLeaveHint方法
mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
...
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
...
现在又跳到了ActivityStack的startActivityLocked方法。
// ActivityStack
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options)
...
if (doResume)
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
ActivityStackSupervisor.resumeTopActivitiesLocked==>ActivityStack.resumeTopActivityLocked==>ActivityStack.resumeTopActivityInnerLocked。
下面来简单看看resumeTopActivityInnerLocked方法。
// ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options)
...
// Find the first activity that is not finishing.
// 找到栈顶正在运行的ActivityRecord
final ActivityRecord next = topRunningActivityLocked(null);
...
// 在真正启动新的Activity之前,这里先暂停以前的Activity。
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
// 第一次进这个方法时,因为老的Activity还没有被暂停,所以这里的
// mResumedActivity不为null,调用startPausingLocked暂停老
// 的Activity。在暂停Activity后,会通知AMS暂停完成,这个时候
// 又会重新调到resumeTopActivityInnerLocked,再次进入这个方法。
if (mResumedActivity != null)
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
...
// 之前暂停Activity后已经return了,这是暂停完成后再次进入这个方法,
// 才会走到这里,next就是被启动的Activity。
if (next.app != null && next.app.thread != null)
// 已有相应进程,不需要创建进程,直接开始创建Activity
...
mStackSupervisor.startSpecificActivityLocked(next, true, false);
...
else
// 被启动的Activity还没有创建相应进程,一般是从Launcher启动应用,
// 或者是从外部调用Activity启动这个应用。这个时候需要创建一个进程,
// 实际由zygote进程fork一个新的进程。
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
创建新的进程
在startSpecificActivityLocked
中,就可以看到是否创建新的进程。
// ActivityStackSupervisor
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig)
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null)
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
...
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
如果有相应进程,直接调realStartActivityLocked
,如果没有,就会调startProcessLocked
来创建新的进程。
来看看创建新进程的过程。
// ActivityManagerService
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge)
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler)
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
...
if (app == null)
...
// 在这里新建了一个ProcessRecord
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
...
...
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
...
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)
...
// 从前面的代码可以看到传入的entryPoint为null,所以在启动新的进程时,
// 传入的entryPoint为"android.app.ActivityThread",这个实际上就
// 是作为新进程main方法入口的类。
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
...
// 这里就是创建新进程了,实际是由zygote进程fork出一个新进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
...
来看看Process的start是怎么处理的。
// Process
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs)
try
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
catch (ZygoteStartFailedEx ex)
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx
synchronized(Process.class)
ArrayList<String> argsForZygote = new ArrayList<String>();
...
// 接下来全都是设置zygote的参数,添加到argsForZygote这个列表中去
...
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
// 顾名思义,这个方法就是打开用来与Zygote进程通信的Socket,如果已经打开,
// 就什么都不用做。在这个方法里可以能看到,有两个可选的Socket:"zygote"
// 和"zygote_secondary",如果首选的"zygote"可以打开,就用"zygote",
// 打不开就再看次选的"zygote_secondary",如果"zygote_secondary"也打
// 不开就会抛异常。
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx
if (primaryZygoteState == null || primaryZygoteState.isClosed())
try
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
catch (IOException ioe)
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
if (primaryZygoteState.matches(abi))
return primaryZygoteState;
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed())
try
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
catch (IOException ioe)
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
if (secondaryZygoteState.matches(abi))
return secondaryZygoteState;
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
private static ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx
try
// 按格式通过Socket来向zygote进程传输参数,然后收到fork的进程id
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
int sz = args.size();
for (int i = 0; i < sz; i++)
String arg = args.get(i);
if (arg.indexOf('\\n') >= 0)
throw new ZygoteStartFailedEx(
"embedded newlines not allowed");
writer.write(arg);
writer.newLine();
writer.flush();
// Should there be a timeout on this?
ProcessStartResult result = new ProcessStartResult();
result.pid = inputStream.readInt();
if (result.pid < 0)
throw new ZygoteStartFailedEx("fork() failed");
result.usingWrapper = inputStream.readBoolean();
return result;
catch (IOException ex)
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
于是,zygote进程就fork出了一个新的进程。
前面说过,在fork新进程时,会传入一个入口类”android.app.ActivityThread”,等fork出新进程后,就会执行这个类的main()方法。所以下面接着来看ActivityThread类的main。
// ActivityThread
public static void main(String[] args)
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null)
sMainThreadHandler = thread.getHandler();
...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
这里实际上就是初始化Looper和ActivityThread,然后用Looper来开始循环分发MessageQueue中的消息。关于Looper、MessageQueue和Handler,这里不做深入探讨,之后另开一贴。接下来看怎么去启动Activity。
// ActivityThread
private void attach(boolean system)
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try
mgr.attachApplication(mAppThread);
catch (RemoteException ex)
// Ignore
...
// ActivityManagerService
@Override
public final void attachApplication(IApplicationThread thread)
synchronized (this)
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid)
...
// See if the top visible activity is waiting to run in this process...
if (normalMode)
try
if (mStackSupervisor.attachApplicationLocked(app))
didSomething = true;
catch (Exception e)
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
...
在这段代码后面还有Service和广播的相关处理,这里不做关注。
// ActivityStackSupervisor
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException
...
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null)
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName))
try
if (realStartActivityLocked(hr, app, true, true))
didSomething = true;
catch (RemoteException e)
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
...
这里就调到了realStartActivityLocked
方法,跟已有进程中启动Activity是一样的。下面直接看这个方法。
已有进程中启动新的Activity
不管是已有进程中启动新的Activity还是先fork新的进程再启动Activity,最终调到的都是realStartActivityLocked
这个方法。
// ActivityStackSupervisor
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, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
实际上这里的app.thread就是之前新建进程后attachApplication
时赋值的,这是一个ApplicationThread实例。
// ActivityThread$ApplicationThread
@Override
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);
sendMessage是发到哪个Handler去处理了呢?看看sendMessage代码。
// ActivityThread
private void sendMessage(int what, Object obj)
sendMessage(what, obj, 0, 0, false);
private void sendMessage(int what, Object obj, int arg1)
sendMessage(what, obj, arg1, 0, false);
private void sendMessage(int what, Object obj, int arg1, int arg2)
sendMessage(what, obj, arg1, arg2, false);
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async)
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async)
msg.setAsynchronous(true);
mH.sendMessage(msg);
可以看到是发给了mH
去处理,而mH
是一个H
实例,H
实际上是一个Handler,在里面统一管理着Activity的生命周期等。
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
// ActivityThread
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent)
...
Activity a = performLaunchActivity(r, customIntent);
if (a != null)
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed)
try
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
...
...
...
这里主要有两个步骤:performLaunchActivity
和handleResumeActivity
。分别会调到onCreate/onStart和onResume方法。而如果Activity没有finish而且是startsNotResumed(这个值实际上是在startSpecificActivityLocked或者realStartActivityLocked时被传进来的,通常可以认为该值为false)的,那么在调完onResume之后,又会立即调用onPause。
// ActivityThread
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
...
// ClassLoader加载指定的Activity类,用newInstance反射的方式创建
// Activity实例,此时仅仅创建了实例,不会调用onCreate等生命周期方法
java.lang.ClassLoader cl = r.packageInfo.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);
...
// makeApplication中会同样以反射的方式创建Application实例,
// 并调用Application的onCreate方法
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
// 在callActivityOnCreate方法中,会调用Activity的onCreate方法
if (r.isPersistable())
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
else
mInstrumentation.callActivityOnCreate(activity, r.state);
...
// performStart会调到onStart方法
if (!r.activity.mFinished)
activity.performStart();
r.stopped = false;
// 如果有之前保存过的状态需要恢复,就会调onRestoreInstanceState
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);
// 调用onPostCreate方法,这个方法平时涉及不会太多
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()");
...
可以看到,这段代码里面主要流程如下:
反射创建Activity实例–>反射创建Application实例–>Application.onCreate–>Activity.onCreate–>Activity.onStart–>Activity.onRestoreInstanceState(如果需要)–>Activity.onPostCreate(不需要关注)。
// ActivityThread
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume)
...
ActivityClientRecord r = performResumeActivity(token, clearHide);
...
// 下面这段代码实际就是将mDecorView添加到Window中并进行绘制的过程。
// 当然,如果之前已经添加过,就不需要再走这些过程
// If the window hasn't yet been added to the window manager,
// and this guy didn't finish itself or start another activity,
// then go ahead and add the window.
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible)
try
willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
a.getActivityToken());
catch (RemoteException e)
if (r.window == null && !a.mFinished && willBeVisible)
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient)
a.mWindowAdded = true;
wm.addView(decor, l);
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
else if (!willBeVisible)
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
...
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide)
...
r.activity.performResume();
...
// Activity
final void performResume()
// 这个方法与onRestart相关,如果Activity是stop状态,那么在这个
// 方法里会依次调到onRestart和onStart
performRestart();
...
// onResume会在这个方法里被调到
mInstrumentation.callActivityOnResume(this);
...
上面的代码可以很明显看出来,在Activity首次创建执行完onResume时,页面实际上还没有显示出来。onResume之后还需要将之前就创建好的mDecorView添加到Window中,然后完成onMeasure、onLayout、onDraw的绘制过程,只有在onDraw完成后,页面才会真正显示出来。Android的官方文档中说,onStart/onStop看成是Activity的可见期,onResume/onPause看成是Activity的可交互期,而从上面的代码就可以看出,这种说法不太准确,在Activity首次创建时,这样的说法是不适用的,当然,抛开首次创建不谈,以后的生命周期确实可以这么简单概括。
以上是关于Activity工作流程的主要内容,如果未能解决你的问题,请参考以下文章
Android基础Activity篇之什么是Activity?