1. 安装应用流程:
PackageManagerService的installPackage 调用 InstallArgs的copyAPK完成了安装。如果在SD卡中,那么调用SdInstallArgs的copyApk完成安装。
2. 应用启动流程:
首先,直接从ActivityManagerService入手,首先调用startActivity这个函数:
public final int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, null, null); }
下面看AcitivityStack,
final int startActivityMayWait(IApplicationThread caller, int callingUid, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler, WaitResult outResult, Configuration config) {
这个函数比较长,下面只看关键部位:
// Collect information about the target of the Intent. ActivityInfo aInfo = resolveActivity(intent, resolvedType, debug, profileFile, profileFd, autoStopProfiler);
这个调到了PackageManager里面的resolveActivity方法里面。这里既暂时不说了。后面再讨论。
往下继续看:
看到一个重量级app的含义,经分析,这样的app会在状态栏,发送一个如下的图标:
所以那段代码直接忽略。往下看,看到如下一句话:
int res = startActivityLocked(caller, intent, resolvedType, grantedUriPermissions, grantedMode, aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, onlyIfNeeded, componentSpecified, null);
这个方法比较长,要有耐性:
ProcessRecord callerApp = null; if (caller != null) { callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null) { 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 = START_PERMISSION_DENIED; } }这段话找出调用者的ProcessRecord
ActivityRecord sourceRecord = null; ActivityRecord resultRecord = null; if (resultTo != null) { int index = indexOfTokenLocked(resultTo); if (DEBUG_RESULTS) Slog.v( TAG, "Will send result to " + resultTo + " (index " + index + ")"); if (index >= 0) { sourceRecord = mHistory.get(index); if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } }
这段话,找出一个resultRecord。
然后是这句话
final int perm = mService.checkComponentPermission(aInfo.permission, callingPid, callingUid, aInfo.applicationInfo.uid, aInfo.exported); 这个是权限检测,后面再说。
下面这句话
if (mMainStack) { if (mService.mController != null) { boolean abort = false; try { // The Intent we give to the watcher has the extra data // stripped off, since it can contain private information. Intent watchIntent = intent.cloneFilter(); abort = !mService.mController.activityStarting(watchIntent, aInfo.applicationInfo.packageName); } catch (RemoteException e) { mService.mController = null; } if (abort) { if (resultRecord != null) { sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, Activity.RESULT_CANCELED, null); } // We pretend to the caller that it was really started, but // they will just get a cancel result. mDismissKeyguardOnNextActivity = false; return START_SUCCESS; } } }
有时候可以设置一个Controller到AcitivytManagerservice中。具体AM.java文件中有引用。例如,从命令行启动Acitivity。
ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified); if (outActivity != null) { outActivity[0] = r; }
if (mMainStack) { if (mResumedActivity == null || mResumedActivity.info.applicationInfo.uid != callingUid) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { PendingActivityLaunch pal = new PendingActivityLaunch(); pal.r = r; pal.sourceRecord = sourceRecord; pal.grantedUriPermissions = grantedUriPermissions; pal.grantedMode = grantedMode; pal.onlyIfNeeded = onlyIfNeeded; mService.mPendingActivityLaunches.add(pal); mDismissKeyguardOnNextActivity = false; return START_SWITCHES_CANCELED; } } if (mService.mDidAppSwitch) { // This is the second allowed switch since we stopped switches, // so now just generally allow switches. Use case: user presses // home (switches disabled, switch to home, mDidAppSwitch now true); // user taps a home icon (coming from home so allowed, we hit here // and now allow anyone to switch again). mService.mAppSwitchesAllowedTime = 0; } else { mService.mDidAppSwitch = true; } mService.doPendingActivityLaunchesLocked(false); }
关键是红色标注的那一句话。
final int N = mPendingActivityLaunches.size(); if (N <= 0) { return; } for (int i=0; i<N; i++) { PendingActivityLaunch pal = mPendingActivityLaunches.get(i); mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, doResume && i == (N-1)); } mPendingActivityLaunches.clear();
把3PendingLaunch的进行启动。
最终进入:
err = startActivityUncheckedLocked(r, sourceRecord, grantedUriPermissions, grantedMode, onlyIfNeeded, true); if (mDismissKeyguardOnNextActivity && mPausingActivity == null) { // Someone asked to have the keyguard dismissed on the next // activity start, but we are not actually doing an activity // switch... just dismiss the keyguard now, because we // probably want to see whatever is behind it. mDismissKeyguardOnNextActivity = false; mService.mWindowManager.dismissKeyguard(); } return err;
err = startActivityUncheckedLocked(r, sourceRecord, grantedUriPermissions, grantedMode, onlyIfNeeded, true); if (mDismissKeyguardOnNextActivity && mPausingActivity == null) { // Someone asked to have the keyguard dismissed on the next // activity start, but we are not actually doing an activity // switch... just dismiss the keyguard now, because we // probably want to see whatever is behind it. mDismissKeyguardOnNextActivity = false; mService.mWindowManager.dismissKeyguard(); } return err;
startActivityUncheckedLocked 这个方法也是很长。
其中FLAG_ACTIVITY_PREVIOUS_IS_TOP 说的是current不是top,之前的是top。也就是说,r不算是top。
ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
if (sourceRecord == null) { // This activity is not being started from another... in this // case we -always- start a new task. if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { Slog.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent); launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; }
不是从Acitivity启动的话,就要加一个newTask标志。这也可以说是同一个task的一个条件吧。
if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // The original activity who is starting us is running as a single // instance... this new activity it is starting must go on its // own task. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
这个说的是如果sourceActivity是一个singleton,那么也启动一个newtask。
else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { // The activity being started is a single instance... it always // gets launched into its own task. launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; }
或者说,自己是一个singletatask或者singleinstance。那么也是newtask。
LAUNCH_SINGLE_INSTANCE 一定是.LAUNCH_SINGLE_TASK,.LAUNCH_SINGLE_TASK 不一定是
LAUNCH_SINGLE_INSTANCE
既然是singletask,那么无法退出结果给 resultTo:
if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // For whatever reason this activity is being launched into a new // task... yet the caller has requested a result back. Well, that // is pretty messed up, so instead immediately send back a cancel // and let the new task continue launched as normal without a // dependency on its originator. Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); sendActivityResultLocked(-1, r.resultTo, r.resultWho, r.requestCode, Activity.RESULT_CANCELED, null); r.resultTo = null; }
下面判断很有意思,如果是一个newTask
if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE)
找到top的task
ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(intent, r.info) : findActivityLocked(intent, r.info);
如果是LAUNCH_SINGLE_INSTANCE,那么就全找。否则,过滤掉LAUNCH_SINGLE_INSTANCE的activity。并且,找到一个task与此相同的。也就是说是new——task,并且不是singleton,这种情况下,找所有task的顶层activity。看是否满足条件。
ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop); if (curTop != null && curTop.task != taskTop.task) { r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); boolean callerAtFront = sourceRecord == null || curTop.task == sourceRecord.task; if (callerAtFront) { // We really do want to push this one into the // user's face, right now. moveHomeToFrontFromLaunchLocked(launchFlags); moveTaskToFrontLocked(taskTop.task, r); } }
新任务与当前的topTask不同的时候,先把home加到前面,然后把当前的加到前面。考虑的时候,排除notTop。
if (onlyIfNeeded) { // We don't need to start a new activity, and // the client said not to do anything if that // is the case, so this is it! And for paranoia, make // sure we have correctly resumed the top activity. if (doResume) { resumeTopActivityLocked(null); } return START_RETURN_INTENT_TO_CALLER; }
不需要启动activity。只是resumetop。
if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 && taskTop.realActivity.equals(r.realActivity)) { logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task); if (taskTop.frontOfTask) { taskTop.task.setIntent(r.intent, r.info); } taskTop.deliverNewIntentLocked(callingUid, r.intent); }
调用onNewInent。如果已经在top,那么就不再启动新的activity。
if (!addingToTask && reuseTask == null) { // We didn't do anything... but it was needed (a.k.a., client // don't use that intent!) And for paranoia, make // sure we have correctly resumed the top activity. if (doResume) { resumeTopActivityLocked(null); } return START_TASK_TO_FRONT; }
不添加新的task,也不用旧的task,就什么都不干。
以上全是处理的newtask,singletask,singleinstance的东西。
if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); // For paranoia, make sure we have correctly // resumed the top activity. if (doResume) { resumeTopActivityLocked(null); } if (onlyIfNeeded) { // We don't need to start a new activity, and // the client said not to do anything if that // is the case, so this is it! return START_RETURN_INTENT_TO_CALLER; } top.deliverNewIntentLocked(callingUid, r.intent); return START_DELIVERED_TO_TOP;
如果是singletop,singletask,并且有一个在top,就直接onNewIntent。
最终进入ActivityStack的
startActivityLocked
最终进入:
private final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition) {
放入activity堆栈后,调用resumeTopActivityLocked final boolean resumeTopActivityLocked(ActivityRecord prev)
然后调用
startSpecificActivityLocked(next, true, true);
这个就是如下代码
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 (r.launchTime == 0) { r.launchTime = SystemClock.uptimeMillis(); if (mInitialStartTime == 0) { mInitialStartTime = r.launchTime; } } else if (mInitialStartTime == 0) { mInitialStartTime = SystemClock.uptimeMillis(); } if (app != null && app.thread != null) { try { app.addPackage(r.info.packageName); 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); }
要么调用 realStartActivityLocked(r, app, andResume, checkConfig);
要么调用 startProcessLocked
realStartActivityLocked 调用 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop);
而 startProcessLocked调用
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {
下面是一些dbug开关。
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);
然后掉到ActivityThread的:
private void attach(boolean system) 方法中
对于非系统进程就这几句话:
ViewRootImpl.addFirstDrawHandler(new Runnable() { public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>"); RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore }
调用到
public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
最终回调到ActivityThread的
private void handleBindApplication(AppBindData data)
等待调试的地方在这个地方:
if (data.debugMode != IApplicationThread.DEBUG_OFF) { // XXX should have option to change the port. Debug.changeDebugPort(8100); if (data.debugMode == IApplicationThread.DEBUG_WAIT) { Slog.w(TAG, "Application " + data.info.getPackageName() + " is waiting for the debugger on port 8100...");
IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.showWaitingForDebugger(mAppThread, true); } catch (RemoteException ex) { }
Debug.waitForDebugger();
try { mgr.showWaitingForDebugger(mAppThread, false); } catch (RemoteException ex) { }
} else { Slog.w(TAG, "Application " + data.info.getPackageName() + " can be debugged on port 8100..."); } }
初始化context
ContextImpl appContext = new ContextImpl(); appContext.init(data.info, null, this); InstrumentationInfo ii = null;
获得apk的信息。 ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; instrApp.dataDir = ii.dataDir; instrApp.nativeLibraryDir = ii.nativeLibraryDir; LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true);
ContextImpl instrContext = new ContextImpl(); instrContext.init(pi, null, this);
初始化instrContext
如果没有instrument则
mInstrumentation = new Instrumentation();
// If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the // app's custom Application class if (!data.restrictedBackupMode){ List<ProviderInfo> providers = data.providers; if (providers != null) { installContentProviders(app, providers); // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } }
try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } }
创造一个应用,并且调用app的 onCreate方法。
下面进入app的onCreate方法
然后
// 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); } }
找到toplevel Activity进行启动。这个toplevelActivity就是刚才要启动的activity。这样activity就与新创建的进程进行了关联。
大小: 903 Bytes 查看图片附件
