Activity 启动流程
Posted Alex_MaHao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity 启动流程相关的知识,希望对你有一定的参考价值。
一下分析基于从Launcher
点击图标打开一个app
进行分析
对于该流程,总共分为三个进程,分别是Launcher
进程,AMS
进程和app
进程,以下会根据该进程流程进行分析。
Launcher
进程,用户点击
LauncherActivity
该页面是桌面的页面,其对应的图标回调如下:
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
Intent intent = intentForPosition(position);
startActivity(intent);
也就是说其实质是调用startActivity()
,该方法来自于Activity
startActivity
并最终调用startActivityForResult
方法
@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
// 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(Intent intent, int requestCode, @Nullable Bundle options)
//一般的Activity其mParent为null,mParent常用在ActivityGroup中,ActivityGroup已废弃 api13
if (mParent == null)
// 负责发起Activity的启动、并具体负责Activity的创建以及Activity生命周期的回调。一个应用进程只会有一个Instrumentation对象,App内的所有Activity都持有该对象的引用
// mMainThread为ActivityThread对象,代表一个应用进程
// mMainThread.getApplicationThread()是一个binder对象,Ams可以通过他通知ActivityThread对象
// mToken 的类型为IBinder对象,它是一个代理对象,指向了ams中的一个类型为ActivityRecord的Binder对象,用来维护Activity的运行状态
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
// ....
Instrumentation
使用来管理activity
声明周期的类,负责activity
的启动等一些功能。
该方法的实质是调用Instrumentation
的execStartActivity()
。
Instrumentation
的execStartActivity()
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options)
// ...
try
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
// 核心方法 通过ActivityManagerNative.getDefault() 获取AMS的代理对象并调用startActivity
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;
该方法实质就是通过ActivityManagerNative
获取到ActivityManagerService
的代理对象ActivityManagerProxy
,通过代理代理对象调用到AMS
的启动activity
方法。
看一下ActivityManagerNative
的getDefault()
方法
通过ActivityManagerNative
获取到ActivityManagerService
的代理对象
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
protected IActivityManager create()
// 获取ams的binder代理
IBinder b = ServiceManager.getService("activity");
if (false)
Log.v("ActivityManager", "default service binder = " + b);
// ActivityManagerProxy 构造amp代理对象
IActivityManager am = asInterface(b);
if (false)
Log.v("ActivityManager", "default service = " + am);
return am;
;
其中asInterface()
方法如下:
*/
static public IActivityManager asInterface(IBinder obj)
if (obj == null)
return null;
// 判断是否是同一进程,如果是统一进程,就不需要包装了。
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null)
return in;
// 否则包装成Proxy对象
return new ActivityManagerProxy(obj);
通过ActivityManagerProxy
对象调用startActivity()
用以通知AMS
// caller 代表launcher所在的applicationThread对象
// intent 包含了所要启动组件的信息
// resultTo 指向AMS内部的ActiityRecord的代理binder对象
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null)
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
else
data.writeInt(0);
if (options != null)
data.writeInt(1);
options.writeToParcel(data, 0);
else
data.writeInt(0);
// 远程binder调用的类型
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
总结
1.LauncherActivity
中的onListItemClick()
处理点击事件,调用Activity
的startActivity()
2.通过层层传递,最终会调用activity
的startForResult()
的方法
3.startActivityForResult()
中会调用Instrumentation
的execStartActivity()
,Instrumentation
为Activity
的管理者,其中的一些生命周期等都会调用该类。
4.在execStartActivity()
中,通过ActivityManagerNative.getDefault()
获取到AMS
的代理对象,其实质是Binder
机制,进行进程间通信。调用远程AMS
的startActivity()
。
5,至此,从Launcher
进程跳转到了AMS
进程。
AMS
进程
在launcher
进程的最后,通过ActivityManagerProxy
代理对象,以binder
的方式,远程调用了AMS
的方法,此时进入到AMS
进程。
调用AMS
的startActivity()
方法
@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)
// startActivity用来处理START_ACTIVITY_TRANSACTION的请求
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)
// 参数说明
// IApplicationThread caller 源进程发起者
// String callingPackage 发起者对应的包名
// Intent intent, String resolvedType, 启动使用的Intent和resolvedType
// IBinder resultTo, String resultWho, int requestCode 回调相关
// int startFlags Intent携带的start activity对应的flag
// ProfilerInfo profilerInfo, 性能统计有关
// Bundle bOptions : ?
// int userId : 调用的用户id
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
// mSupervisor的类型为ActivityStackSupervisor, 负责管理Activity和对应Task之间的关系
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
AMS
收到请求后会通过mStackSupervisor
的startActivityMayWait
完成获取的页面跳转。其中ActivityStacksupervisor
是用来管理ActvityStack
的。
ActivityStackSupervisor
的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 config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask)
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors())
throw new IllegalArgumentException("File descriptors passed in Intent");
// 判断是否指定了组件名
boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// 获取activity的一些信息, 通过PackageManagerService
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
ActivityContainer container = (ActivityContainer)iContainer;
synchronized (mService)
// 此处container为null
if (container != null && container.mParentActivity != null &&
container.mParentActivity.state != RESUMED)
// Cannot start a child activity if the parent is not resumed.
return ActivityManager.START_CANCELED;
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
if (callingUid >= 0)
callingPid = -1;
else if (caller == null)
callingPid = realCallingPid;
callingUid = realCallingUid;
else
callingPid = callingUid = -1;
// 启动时的activity栈
final ActivityStack stack;
if (container == null || container.mStack.isOnHomeDisplay())
// 获取当前的任务栈
stack = mFocusedStack;
else
//当从一个Activity启动另一个Activity时,
//启动栈为父Activity的Task
stack = container.mStack;
// 为false 因为config为null
stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
// androidManifest.xml中的Application标签可以申明一个CANT_SAVE_STATE属性 ,被称为heavy-weight process
// 这个没用过,所以这段逻辑不会走
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0)
// ...
// 继续执行startActivity的启动
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
// ...
// outResult为null ,所以该段逻辑不会走
if (outResult != null)
// ...
return res;
通过PackageManagerService
查询要启动的目标activity
的一些信息。
调用startActivityLocked()
ActivityStackSupervisor
的startActivityLocked()
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)
// 用于保存错误信息
int err = ActivityManager.START_SUCCESS;
// 用户获取源进程的信息
ProcessRecord callerApp = null;
// 如果参数中的调用者不为空,则从AMS中找到对应的ProcessRecord,目的是得到调用者的pid和uid
if (caller != null)
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null)
// 保存 pid 和 uid
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
else
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
if (err == ActivityManager.START_SUCCESS)
Slog.i(TAG, "START u" + userId + " " + intent.toShortString(true, true, true, false)
+ " from uid " + callingUid
+ " on display " + (container == null ? (mFocusedStack == null ?
Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
(container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
container.mActivityDisplay.mDisplayId)));
// sourceRecord用于保存源进程actvity的信息
ActivityRecord sourceRecord = null;
// 如果需要获取result则将源进程actvity保存到此
ActivityRecord resultRecord = null;
// 通过resultTo 来找到Launcher所对应的activityRecord
if (resultTo != null)
sourceRecord = isInAnyStackLocked(resultTo);
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
if (sourceRecord != null)
if (requestCode >= 0 && !sourceRecord.finishing)
resultRecord = sourceRecord;
//得到启动Activity使用的标志位
final int launchFlags = intent.getFlags();
// 没用过,忽略。。。FLAG_ACTIVITY_FORWARD_RESULT
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null)
// ....
// 检查一些条件
// ....
// 得到接受启动结果的task
final ActivityStack resultStack = resultRecord == null ? null : resultRecord解锁的framework流程与解锁后的加载动画
深入理解Activity启动流程–Activity Task的调度算法