关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
目录
- 一、概览
- 二、应用内启动源码流程 (startActivity)
- 2.1 startActivity()
- 2.2 startActivityAsUser()
- 2.3 startActivityUnchecked()
- 2.4 resumeFocusedStackTopActivityLocked()
- 2.5 startSpecificActivityLocked -> realStartActivityLocked()
- 三、 Activity实例化过程
- 四、 setContentView
- 五、 后续生命周期
- 六、 推荐阅读
学习前,建议有相关知识储备:
【Android 基础】 应用(Application)启动流程
通过本文你可以学习到Activity启动流程。
一、概览
Activity 是 android 四大组件之一,很有必要知道它的启动过程,我们在上一篇文章中介绍了 APP的启动流程,里面大概讲到了Activity的
启动流程,在本文中,我们系统的再总结一下,当成一个记录。
Activity 的启动方式我们讲有两种,一种是在应用内部启动,另一种是外部启动,比如Launcher;
- 应用内启动
通过 startActivity、startActivityForResult等方式来启动 Activity
其流程我们总结下:
1、调用 Activity 的 startActivity 方法来启动目标 Activity
2、接着就会调用到 Instrunmentation 的 execStartActivity 方法,然后调用到 AMS 的 startActivity 中去
3、调用到 AMS 中后,会执行到ActivityStarter 的 execute 方法,接着就会进行一些校验和判断权限,包括进程检查,intent检查,权限检查、是否启用新栈等
4、所有的信息存储在ActivityRecord中,ActivityRecord是Activity在system_server进程中的镜像,Activity实例与ActivityRecord实例一一对应。ActivityRecord用来存储Activity的信息,如所在的进程名称,应用的包名,所在的任务栈的taskAffinity等
5、中间再经过一系列调用,又回调到 ActivityThread 的 handleLaunchActivity 来启动 Activity。
借用一张网络图片
- 应用外启动
通过Launcher 进程启动,Launcher 就是我们桌面程序,当系统开机后, Launcher 也随之被启动。
1、fork并调用ActivityThread的main方法创建app进程
2、然后从 ActivityThread 调用到AMS中的attachApplicationLocked,创建Application
3、Application创建完后,调用ActivityStackSupervisor的attachApplicationLocked方法,最终调用到handleLaunchActivity,进行activity的创建
二、应用内启动源码流程 (startActivity)
我们就从源码出发,一起来看看startActivity后面的流程
2.1 startActivity()
Activity.java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
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());
}
} else {
// 最终也是调用 execStartActivity 方法,源码如下
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
上面代码中,最终都会调用了 execStartActivity 方法,该方法会返回一个启动结果。我们一起来看看
frameworks/base/core/java/android/app/Instrumentation.java
/**
*
* @param who 用来启动 Activity 的对象
* @param contextThread Binder 对象,具有跨进程通信的能力,传入的是 ApplicationThread
* @param token Binder 对象,指向了服务端一个 ActivityRecord 对象
* @param target 当前的 Activity
* @param intent Intent 对象
* @param requestCode 请求码
*/
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 这里的service 就是 ActivityManagerService, 具体可以跟代码看到
// 这么一句 : ServiceManager.getService(Context.ACTIVITY_SERVICE);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
通过 Binder 调用 AMS 启动 Activity,我们接着往下看
2.2 startActivityAsUser()
ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
@Override
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,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
// 首先 检查调用者权限
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
最后调用的是 ActivityStarter.execute();
上面代码最终调用到了 startActivityAsUser 方法,在内部将所有点的参数都交给了 ActivityStarter
2.3 startActivityUnchecked()
ActivityStarter 该类包含了启动的所有逻辑,比如 Intent 解析以及任务栈等。
ActivityStarter.java
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, ...);
} else {
// todo
return startActivity(mRequest.caller, ...);
}
} finally {
onExecutionComplete();
}
}
private int startActivity(IApplicationThread caller, Intent intent, ...) {
// 再次检查调用者权限,包括进程检查,intent检查,权限检查等
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, ...);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, ...);
// 每个 Activity 都会对应一个 ActivityRecord 对象
ActivityRecord r = new ActivityRecord(mService, ...);
// todo
result = startActivityUnchecked(r, sourceRecord ...);
}
// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord ...) {
//设置初始化状态
setInitialState(r, options, inTask, ...);
//判断启动模式,并且在 mLaunchFlags 上追加对应标记
computeLaunchingTaskFlags();
//设置 Activity 的栈
computeSourceStack();
//设置 LaunchFlags 到 intent 上
mIntent.setFlags(mLaunchFlags);
//决定是否用新的栈
ActivityRecord reusedActivity = getReusableIntentActivity();
...
// Should this be considered a new task?
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
// 创建一个新的task来启动
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
} else
// todo
mSupervisor.resumeFocusedStackTopActivityLocked();
}
上面代码中会进行一些校验和判断权限,包括进程检查,intent检查,权限检查等
2.4 resumeFocusedStackTopActivityLocked()
ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack...) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
return false;
}
resumeTopActivityUncheckedLocked -> resumeTopActivityInnerLocked -> startSpecificActivityLocked()
ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
Activity 存在则resume
transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.repProcState,。。。);
mService.getLifecycleManager().scheduleTransaction(transaction);
不存在则调用下面这个
result = resumeTopActivityInnerLocked(prev, options);
} finally {
}
return result;
}
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
2.5 startSpecificActivityLocked -> realStartActivityLocked()
ActivityStackSupervisor.java
startSpecificActivityLocked -> realStartActivityLocked(); 到这个地方,我们就可以看到真的开始启动 activity,
后面就跟Application 里面一样了
void startSpecificActivityLocked(ActivityRecord r ...) {
if (app != null && app.thread != null) {
try {
// 真的开始启动 activity ,看下面的方法
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
}
真的开始启动 activity
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
ActivityManagerService
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
ClientLifecycleManager
通过代码,我们可以看到,获取的client就是 ActivityThread,IApplicationThread是一个AIDL文件
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
}
ClientTransaction
/** Target client. */
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
ClientTransactionHandler
//ActivityThread中没有复写scheduleTransaction,会执行到父类的方法
//public final class ActivityThread extends ClientTransactionHandler
//ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
//发送消息
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
ActivityThread.java
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
break;
这里其实就是执行LaunchActivityItem的execute方法,
其赋值的地方在realStartActivityLocked()方法,大家可以回头看看,前面有这么一句代码
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
TransactionExecutor.java
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}
到这里就调用到我们熟悉的handleLaunchActivity了
LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
最后调用到ActivityThread
三、 Activity实例化过程
ActivityThread.java
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
final Activity a = performLaunchActivity(r, customIntent);
return a;
}
Activity实例化过程
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
try {
// 通过ClassLoader去加载需要启动的activity, 反射实例化Activity对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
} catch (Exception e) {
}
// 在该方法内部创建window,并设置window回调,
activity.attach(appContext, this, getInstrumentation() ...);
theme
//当实例化Activity对象后,继续执行callActivityOnCreate, 继而调用Activity的onCreate,
// 这样就完成了Activity生命周期的第一个回调onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
下面的代码比较简单,就不贴了
frameworks/base/core/java/android/app/Instrumentation.java
四、 setContentView
这里内容太多,我们另外写一篇文章。
五、 后续生命周期
接下来就是执行 Activity 其他生命周期函数
ActivityThread.java
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
// Restore instance state
if (pendingActions.shouldRestoreInstanceState()) {
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);
}
}
// Call postOnCreate()
if (pendingActions.shouldCallOnPostCreate()) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
}
}
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
}
写在最后:
在应用进程创建 activity 后,activity 将执行以下操作:
- 初始化值。
- 调用构造函数。
- 根据 activity 的当前生命周期状态,相应地调用回调方法,如 Activity.onCreate()。
通常,onCreate() 方法对加载时间的影响最大,因为它执行工作的开销最高:加载和渲染视图,以及初始化运行 activity 所需的对象。
六、 推荐阅读
Java 专栏
SQL 专栏
数据结构与算法
Android学习专栏