主要参考的源码为Android2.3与8.0,从姜饼到奥瑞奥,Activity的主要逻辑并没有根本性的改变,更多是做了一些封装和优化,下文会在版本变化中对相关变化的代码进行对比和说明。
Launcher发送start请求
1 Launcher.startActivitySafely
系统启动时 PackageManagerService 解析 Androidmainfest文件, 会获取启动需要的laucher等信息,详情见《安卓源码分析与演变——PackageManager全流程》
之后根据flag走相应的启动流程
public ListqueryIntentActivities(Intent intent,
String resolvedType, int flags) {
ComponentName comp = intent.getComponent();
if (comp != null) {
Listlist = new ArrayList (1);
ActivityInfo ai = getActivityInfo(comp, flags);
if (ai != null) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
return (List)mActivities.queryIntent(intent,
resolvedType, flags);
}
PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return (List) mActivities.queryIntentForPackage(intent,
resolvedType, flags, pkg.activities);
}
return null;
}
}
void startActivitySafely(Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Launcher does not have the permission to launch " + intent +
". Make sure to create a MAIN intent-filter for the corresponding activity " +
"or use the exported attribute for this activity. "
+ "tag="+ tag + " intent=" + intent, e);
}
}
2 Activity.startActivity
@Override
public void startActivity(Intent intent) {
startActivityForResult(intent, -1);
}
3 startActivityForResult
Instrument 监护系统和应用交互
ActivityThread 每个应用进程启动持有,拥有ApplicationThread变量(Binder本地对象),作为参数传递给ActivityManagerService,通知组件进入
paused状态
Activity的mToken为Ibinder(代理对象),指向ActivityManagerService的ActivityRecord
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
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;
}
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
4 Instrument.execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i final ActivityMonitor am = mActivityMonitors.get(i);if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {int result = ActivityManagerNative.getDefault().startActivity(whoThread, intent,intent.resolveTypeIfNeeded(who.getContentResolver()),null, 0, token, target != null ? target.mEmbeddedID : null,requestCode, false, false);checkStartActivityResult(result, intent);} catch (RemoteException e) {}return null;}
版本变化
2.3版本
ActivityManagerNative.getDefalt获取ActivityManagerService的代理对象,封装为ActivityManagerProxy
static public IActivityManager getDefault(){if (gDefault != null) {//if (Config.LOGV) Log.v(// "ActivityManager", "returning cur default = " + gDefault);return gDefault;}IBinder b = ServiceManager.getService("activity");if (Config.LOGV) Log.v("ActivityManager", "default service binder = " + b);gDefault = asInterface(b);if (Config.LOGV) Log.v("ActivityManager", "default service = " + gDefault);return gDefault;}8.0版本
int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);取代了之前的ActivityManagerNative和proxy类,直接获取封装过的单例aidl接口IActivityManager,包括startservice等大量方法
调用asInterface()将服务端的Binder对象转换为客户端所需要的AIDL接口类型。如果客户端和服务端在同一个进程他返回的就是服务端Stub对象本身,否则返回封装的Stub.proxy对象。
private static final SingletonIActivityManagerSingleton = new Singleton() { @Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};//ServiceManager实质上是管理缓存的Ibinder对象public static IBinder getService(String name) {try {IBinder service = sCache.get(name);if (service != null) {return service;} else {return Binder.allowBlocking(getIServiceManager().getService(name));}} catch (RemoteException e) {Log.e(TAG, "error in getService", e);}return null;}5 ActivityManagerNative.ActivityManagerProxy.startActivity
参数传递为Parcel,反序列化对象
通过ActivityManagerProxy的mRemote发送START_ACTIVITY_TRANSACTION,即进程间通信请求
(Proxy类实现IActivityManager接口,而8.0将中转的代理类去除,精简了流程)
public int startActivity(IApplicationThread caller, Intent intent,String resolvedType, Uri[] grantedUriPermissions, int grantedMode,IBinder resultTo, String resultWho,int requestCode, boolean onlyIfNeeded,boolean debug) throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(caller != null ? caller.asBinder() : null);intent.writeToParcel(data, 0);data.writeString(resolvedType);data.writeTypedArray(grantedUriPermissions, 0);data.writeInt(grantedMode);data.writeStrongBinder(resultTo);data.writeString(resultWho);data.writeInt(requestCode);data.writeInt(onlyIfNeeded ? 1 : 0);data.writeInt(debug ? 1 : 0);mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);reply.readException();int result = reply.readInt();reply.recycle();data.recycle();return result;}
AMS处理start请求并发送paused
6 ActivityManagerService.startActivity
成员函数ActivityStack处理IPC请求,启动组件
public final int startActivity(IApplicationThread caller,Intent intent, String resolvedType, Uri[] grantedUriPermissions,int grantedMode, IBinder resultTo,String resultWho, int requestCode, boolean onlyIfNeeded,boolean debug) {return mMainStack.startActivityMayWait(caller, intent, resolvedType,grantedUriPermissions, grantedMode, resultTo, resultWho,requestCode, onlyIfNeeded, debug, null, null);}版本变化
8.0 使用了ActivityStarter,封装了ActivityStack、ActivityRecord、flag,intent相关的处理
@Overridepublic 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());}
@Overridepublic 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, null,"startActivityAsUser");}7 ActivityStack.startActivityMayWait
解析intent信息
final int startActivityMayWait(IApplicationThread caller,Intent intent, String resolvedType, Uri[] grantedUriPermissions,int grantedMode, IBinder resultTo,String resultWho, int requestCode, boolean onlyIfNeeded,boolean debug, WaitResult outResult, Configuration config) {ActivityInfo aInfo;try {ResolveInfo rInfo =AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,PackageManager.MATCH_DEFAULT_ONLY| ActivityManagerService.STOCK_PM_FLAGS);aInfo = rInfo != null ? rInfo.activityInfo : null;} catch (RemoteException e) {aInfo = null;}...int res = startActivityLocked(caller, intent, resolvedType,grantedUriPermissions, grantedMode, aInfo,resultTo, resultWho, requestCode, callingPid, callingUid,8 ActivityStack.startActivityLocked
ActivityManagerService获取Caller对应的Proce***ecord对象,该对象指向Launcher所在进程,获取pid和uid
从mHistory寻找ActivityRecord信息,保存变量sourceActivity
9 ActivityStack.startActivityUnCheckedLocked
判断标志位,是否新task,是否用户操作,根据taskAffinity属性判断新Activity的task组归属
重载方法startActivityLocked,加入栈顶,保存history
final int startActivityUncheckedLocked(ActivityRecord r,ActivityRecord sourceRecord, Uri[] grantedUriPermissions,int grantedMode, boolean onlyIfNeeded, boolean doResume) {final Intent intent = r.intent;final int callingUid = r.launchedFromUid;int launchFlags = intent.getFlags();ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)!= 0 ? r : null;// Should this be considered a new task?if (r.resultTo == null && !addingToTask&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {// todo: should do better management of integers.mService.mCurTask++;if (mService.mCurTask <= 0) {mService.mCurTask = 1;}r.task = new TaskRecord(mService.mCurTask, r.info, intent,(r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r+ " in new task " + r.task);newTask = true;if (mMainStack) {mService.addRecentTaskLocked(r.task);}} else if (sourceRecord != null) {if (!addingToTask &&(launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {10 ActivityStack.resumeTopActivityLocked
如果将要启动的Activity已经resume或者pause直接返回,否则通知进入pause状态准备启动
final boolean resumeTopActivityLocked(ActivityRecord prev) {// Find the first activity that is not finishing.ActivityRecord next = topRunningActivityLocked(null);...// If the top activity is the resumed one, nothing to do.if (mResumedActivity == next && next.state == ActivityState.RESUMED) {// Make sure we have executed any pending transitions, since there// should be nothing left to do at this point.mService.mWindowManager.executeAppTransition();mNoAnimActivities.clear();return false;}// 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)&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {// Make sure we have executed any pending transitions, since there// should be nothing left to do at this point.mService.mWindowManager.executeAppTransition();mNoAnimActivities.clear();return false;}// The activity may be waiting for stop, but that is no longer// appropriate for it.mStoppingActivities.remove(next);mWaitingVisibleActivities.remove(next);// We need to start pausing the current activity so the top one// can be resumed...if (mResumedActivity != null) {if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");startPausingLocked(userLeaving, false);return true;}...}版本变化
8.0
ActivityStackSupervisor封装了ActivityStack有关的方法
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {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;}11 startPausingLocked
调用AMP通知主Activity,进入pause状态。延时发送handler超时消息
private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {ActivityRecord prev = mResumedActivity;...if (prev.app != null && prev.app.thread != null) {if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);try {EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,System.identityHashCode(prev),prev.shortComponentName);prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,prev.configChangeFlags);if (mMainStack) {mService.updateUsageStats(prev, false);}} catch (Exception e) {// Ignore exception, if process died other code will cleanup.Slog.w(TAG, "Exception thrown during pause", e);mPausingActivity = null;mLastPausedActivity = null;}} else {mPausingActivity = null;mLastPausedActivity = null;}...if (mPausingActivity != null) {// Schedule a pause timeout in case the app doesn't respond.// We don't give it much time because this directly impacts the// responsiveness seen by the user.Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);msg.obj = prev;mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");} else {// This activity failed to schedule the// pause, so just treat it as being paused now.if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");resumeTopActivityLocked(null);}}
case PAUSE_TIMEOUT_MSG: {IBinder token = (IBinder)msg.obj;// We don't at this point know if the activity is fullscreen,// so we need to be conservative and assume it isn't.Slog.w(TAG, "Activity pause timeout for " + token);activityPaused(token, null, true);}12 APN.ApplicationThreadProxy.scheduePauseActivity
Ibinder发往Laucher组件(异步请求)
public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges) throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);data.writeStrongBinder(token);data.writeInt(finished ? 1 : 0);data.writeInt(userLeaving ? 1 :0);data.writeInt(configChanges);mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();}Launcher进入Pause状态
以上过程都在Laucher完成
13 ApplicationThread.scedulePauseActivity
binder指向ActivityRecord
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Bundle state, ListpendingResults, ListpendingNewIntents, boolean notResumed, boolean isForward) { ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.activityInfo = info;r.state = state;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;queueOrSendMessage(H.LAUNCH_ACTIVITY, r);}14 ActivityThread.queueOrSendMessage
mH处理主线程pause操作
15 ActivityThread.handleMessage
16 ActivityThread.handlePauseActivity
通知Launcher 用户离开
通知Launcher onPause
queueWork wait数据写入(以备onResume恢复)
通知ActivityManagerService pause
private final void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges) {ActivityClientRecord r = mActivities.get(token);if (r != null) {//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);if (userLeaving) {performUserLeavingActivity(r);}r.activity.mConfigChangeFlags |= configChanges;Bundle state = performPauseActivity(token, finished, true);// Make sure any pending writes are now committed.QueuedWork.waitToFinish();// Tell the activity manager we have paused.try {ActivityManagerNative.getDefault().activityPaused(token, state);} catch (RemoteException ex) {}}}版本变化
8.0
private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) {ActivityClientRecord r = mActivities.get(token);if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {return;}if (r != null) {//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);if (userLeaving) {performUserLeavingActivity(r);}r.activity.mConfigChangeFlags |= configChanges;performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");// Make sure any pending writes are now committed.if (r.isPreHoneycomb()) {QueuedWork.waitToFinish();}// Tell the activity manager we have paused.if (!dontReport) {try {ActivityManager.getService().activityPaused(token);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}mSomeActivitiesChanged = true;}}17 ActivityManagerProxy.activityPaused
parcel封装数据
mRemote通知ActivityManagerService(IPC)
public void activityPaused(IBinder token, Bundle state) throws RemoteException{Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(token);data.writeBundle(state);mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);reply.readException();data.recycle();reply.recycle();}AMS准备启动新进程
18 ActivityManagerService.activityPaused
public final void activityPaused(IBinder token, Bundle icicle) {// Refuse possible leaked file descriptorsif (icicle != null && icicle.hasFileDescriptors()) {throw new IllegalArgumentException("File descriptors passed in Bundle");}final long origId = Binder.clearCallingIdentity();mMainStack.activityPaused(token, icicle, false);Binder.restoreCallingIdentity(origId);}19 ActivityStack.activityPaused
移除超时
获取stack中的ActivityRecord
public final void activityPaused(IBinder token, Bundle icicle) {// Refuse possible leaked file descriptorsif (icicle != null && icicle.hasFileDescriptors()) {throw new IllegalArgumentException("File descriptors passed in Bundle");}final long origId = Binder.clearCallingIdentity();mMainStack.activityPaused(token, icicle, false);Binder.restoreCallingIdentity(origId);}20 ActivityStack.completePauseLocked
使pre指向mPausingActivity,并置空mPausingActivity,表示已完成pause
非睡眠和关闭状态执行resume
private final void completePauseLocked() {ActivityRecord prev = mPausingActivity;if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);if (prev != null) {if (prev.finishing) {if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);} else if (prev.app != null) {if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);if (prev.waitingVisible) {prev.waitingVisible = false;mWaitingVisibleActivities.remove(prev);if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG, "Complete pause, no longer waiting: " + prev);}if (prev.configDestroy) {destroyActivityLocked(prev, true);} else {mStoppingActivities.add(prev);if (mStoppingActivities.size() > 3) {// If we already have a few activities waiting to stop,// then give up on things going idle and start clearing// them out.if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");Message msg = Message.obtain();msg.what = IDLE_NOW_MSG;mHandler.sendMessage(msg);}}} else {if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);prev = null;}mPausingActivity = null;}if (!mService.mSleeping && !mService.mShuttingDown) {resumeTopActivityLocked(prev);} else {if (mGoingToSleep.isHeld()) {mGoingToSleep.release();}if (mService.mShuttingDown) {mService.notifyAll();}}}21 ActivityStack.resumeActivityLocked
此时mResumeAcitivity为空,并且未启动新的app进程,执行startSpecificActivityLocked
final boolean resumeTopActivityLocked(ActivityRecord prev) {...if (mResumedActivity != null) {if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");startPausingLocked(userLeaving, false);return true;}if (next.app != null && next.app.thread != null) {...next.app.thread.scheduleResumeActivity(next,mService.isNextTransitionForward());pauseIfSleepingLocked();...} else {startSpecificActivityLocked(next, true, false);return true;}}22 ActivityStack.startSpecificActivityLocked
根据应用进程名称和用户id(每个activity相对应)启动Activity,如果不存在创建相应进程,根Activity在此处初次创建进程
private final void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?Proce***ecord app = mService.getProce***ecordLocked(r.processName,r.info.applicationInfo.uid);...if (app != null && app.thread != null) {try {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);}23 ActivityManagerService.startProcessLocked
newProce***ecordLocked 保存进程对应record
重载函数创建进程
发送PROC_START_TIMEOUT_MSG 新进程要求20毫秒内启动完成 否则超时
Process.start
private final void startProcessLocked(Proce***ecord app,String hostingType, String hostingNameStr) {...int pid = Process.start("android.app.ActivityThread",mSimpleProcessManagement ? app.processName : null, uid, uid,gids, debugFlags, null);if (pid == 0 || pid == MY_PID) {// Processes are being emulated with threads.app.pid = MY_PID;app.removed = false;mStartingProcesses.add(app);} else if (pid > 0) {app.pid = pid;app.removed = false;synchronized (mPidsSelfLocked) {this.mPidsSelfLocked.put(pid, app);Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);msg.obj = app;mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);}} else {app.pid = 0;RuntimeException e = new RuntimeException("Failure starting process " + app.processName+ ": returned pid=" + pid);Slog.e(TAG, e.getMessage(), e);}...}新应用进程启动
24 ActivityThread.main
main方法-looper.prepare-thread.attach-looper.loop-thread.detach
thread为ActivityThread,内部初始化ApplicationThread(binder本地对象,ActivityManagerService通信)
public static final void main(String[] args) {SamplingProfilerIntegration.start();Process.setArgV0(""); Looper.prepareMainLooper();if (sMainThreadHandler == null) {sMainThreadHandler = new Handler();}ActivityThread thread = new ActivityThread();thread.attach(false);if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();if (Process.supportsProcesses()) {throw new RuntimeException("Main thread loop unexpectedly exited");}thread.detach();String name = (thread.mInitialApplication != null)? thread.mInitialApplication.getPackageName(): ""; Slog.i(TAG, "Main thread of " + name + " is now exiting");}25 ActivityThread.attachApplication
public void attachApplication(IApplicationThread app) throws RemoteException{Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(app.asBinder());mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);reply.readException();data.recycle();reply.recycle();}26 ActivityManagerService.attachApplication
public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}}27 ActivityManagerService attachApplicationLocked
使Proce***ecord.thread指向IApplicationThread(IPC),ActivityManagerService 即可以通过该对象与app进行通信
进程启动完成 移除超时msg
获取顶端 ActivityRecord,realStartActivityLocked
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {Proce***ecord app;...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.debugging = false;mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);...// See if the top visible activity is waiting to run in this process...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 {mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);}}}29 ActivityStack.realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r,Proce***ecord app, boolean andResume, boolean checkConfig)throws RemoteException {...r.app = app;if (localLOGV) Slog.v(TAG, "Launching: " + r);int idx = app.activities.indexOf(r);if (idx < 0) {app.activities.add(r);}...mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());app.thread.scheduleLaunchActivity(new Intent(r.intent), r,System.identityHashCode(r),r.info, r.icicle, results, newIntents, !andResume,mService.isNextTransitionForward());...return true;}ActivityRecord加入app的ac列表
app.thread准备启动ac
(Proce***ecord.thread指向IApplicationThread(IPC),ActivityManagerService 即可以通过该对象与app进行通信)
29 ApplicationThreadNative.scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Bundle state, ListpendingResults, ListpendingNewIntents, boolean notResumed, boolean isForward) throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);intent.writeToParcel(data, 0);data.writeStrongBinder(token);data.writeInt(ident);info.writeToParcel(data, 0);data.writeBundle(state);data.writeTypedList(pendingResults);data.writeTypedList(pendingNewIntents);data.writeInt(notResumed ? 1 : 0);data.writeInt(isForward ? 1 : 0);mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();}主线程启动Activity
30 ActivityThread.ApplicationThread.scheduleLaunchActivity
// we use token to identify this activity without having to send the// activity itself back to the activity manager. (matters more with ipc)public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Bundle state, ListpendingResults, ListpendingNewIntents, boolean notResumed, boolean isForward) { ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.activityInfo = info;r.state = state;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;queueOrSendMessage(H.LAUNCH_ACTIVITY, r);}封装ActivityClientRecord信息,主线程LAUNCH_ACTIVITY
31 ActivityThread.queueOrSendMessage
32 HandleMsg
public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);switch (msg.what) {case LAUNCH_ACTIVITY: {ActivityClientRecord r = (ActivityClientRecord)msg.obj;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo);handleLaunchActivity(r, null);} break;}}getPackageInfoNoCheck,返回LoadedApk 已加载的apk信息
把它赋予ActivityClientRecord
33 handleLaunchActivity
private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();if (localLOGV) Slog.v(TAG, "Handling launch of " + r);Activity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);Bundle oldState = r.state;handleResumeActivity(r.token, false, r.isForward);...}34 performLaunchActivity
初始化context和application
mInstrumentation.callActivityOnCreate启动activity并恢复状态
mActivities.put(r.token, r); 将toke和ActivityClientRecord对应保存
注意:ActivityClientRecord的token是Binder代理对象,指向ActivityManagerService中的ActivityRecord,双方只是在不同进程使用。
private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");ActivityInfo aInfo = r.activityInfo;if (r.packageInfo == null) {r.packageInfo = getPackageInfo(aInfo.applicationInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentName component = r.intent.getComponent();if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}Activity activity = null;try {java.lang.ClassLoader cl = r.packageInfo.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);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);。。。mInstrumentation.callActivityOnCreate(activity, r.state);...35 MainActivity.onCreate
来到大家最熟悉的方法了,流程完结。
总结
1、Launcher组件、MainActivity组件、AMS(ActivityManagerService),这三者的交互为核心,而这三者分属不同进程,以Binder作为通信工具进行交互。
2、主流程:Launcher通知AMS并等待启动——AMS准备启动MainActivity——创建新进程——AMS通知新进程ActivityThread启动MainActivity
3、ActivityManagerNative通过ServiceManager获得AMS的代理对象,实现应用与AMS通信;AMS通过ApplicationThreadProxy获取Launcher代理对象,实现AMS与应用通信。