Activity启动流程
本文章基于Android6.0源码
1. Activity冷启动
冷启动表示启动的时候没有没有当前应用进程,需要首先启动进程,然后再启动当前Activity或者Service,或者BroadCastReceiver。
2. Activity热启动
表示当前应用进程已经起来,只需要直接启动一个Activity,service就行,
3. Activity启动的流程图
本图基于Android6.0源码,如有疑问欢迎留言,并且欢迎提出问题,可以一同解答。 其实对着当前这个流程图已经大致将Activity启动流程进行了反应。
Activity启动流程.png
存在问题:
- 目前缺少的是AMS通过 Process.start 方法启动一个Process, 这个Process是如何走到ActivityThread中去的
- **ActivityStackSupervisor.startSpecificActivityLocked **这个方法是怎么进去的,这里的处理很多,目前也不是很明白
4. 关键代码解析
4.1 Activity.startActivity
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
//这里就直接走到Instrumenttation类,来执行Start
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);
} else {
// ...忽略
}
}
4.2 Instrumentation.execStartActivity
Instrumentation 仪器,乐谱)类是一个非常关键的类, 在一个进程中,Activity生命周期的操作,甚至Application的生命周期的操作都是通过它来执行的,可以说 他就是APP生命活动的 乐谱。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
//...省略一部分代码
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这里 ActivityManagerNative.getDefault() 这个方法其实去获取到ActivityManagerProxy,来拿到AMS的代理类,通过Binder来执行跨进程调用,这里就是第一次发生跨进程调用的地方。
Activity进程 ---> SystemServer 进程
这里顺便提一下,AMS是怎么把自己加入到ServiceManager中的。
- ActivityManagerNative中是通过 ServiceManager和activity名字来获取到ActivityManagerProxy的client对象的。
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;
}
};
}
-
在AMS启动过程中,会调用一个**setSystemProcess ** 在这里,AMS会把自己添加到服务端里面。
public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this)); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this)); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); synchronized (this) { ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); app.persistent = true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); synchronized (mPidsSelfLocked) { mPidsSelfLocked.put(app.pid, app); } updateLruProcessLocked(app, false, null); updateOomAdjLocked(); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } }
4.3 AMS 执行Activity启动
通过一次跨进程Binder调用之后,AMS开始执行startActivity流程。这里基本没有什么. Android6.0 已经将之前很多复杂的启动流程进行了优化(少了ActiivtyStarter,等等类),但是基本的流程是不变的。
@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);
}
4.4 ActivityStackSupervisor
ActivityStackSupervisor在真实启动Activity之前,会针对Intent来进行Resolve,将 Intent指向 的启动类 通过PMS(PackageManagerServcie) 来解析出来。如果找不到响应当前Intent的类,那么就会报启动异常
* 如果执行错误,会将错误结果返回给 **Instrumentation** 调用 **checkStartActivityResult(result, intent);**
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);
// Collect information about the target of the Intent
//这里针对当前的intentn进行一次解析,涉及到了PMS(Actiivty安装管理流程)
//如果这里针对intent解析没有出来, 就可能抛出异常表示没有找到目标Activity
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
ActivityContainer container = (ActivityContainer)iContainer;
// 这里解析之后,就执行 startActivityLocked.
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
这个方法比较长,但是发现Android源码中一个比较好的点就是 一个方法中,前半段基本都是条件检查,真正执行的代码一般都在最后。
这里的关键方法就是: startActivityUncheckedLocked
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;
...
// 这里 省略的一段就是执行 intent检查,看是否有目标Actiivty响应 intet,或者启动Activity是否权限之类的。
doPendingActivityLaunchesLocked(false);
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
if (err < 0) {
// If 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.
notifyActivityDrawnForKeyguard();
}
return err;
}
执行 startActivityUncheckedLocked
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
...
//这里前半段就是检查当前启动的activity栈是否存在,如果存在就直接将当acitivyt进行栈操作。
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
intent, r.getUriPermissionsLocked(), r.userId);
if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
}
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
}
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
targetStack.mLastPausedActivity = null;
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
if (!launchTaskBehind) {
// Don't set focus on an activity that's going to the back.
mService.setFocusedActivityLocked(r, "startedActivity");
}
return ActivityManager.START_SUCCESS;
}
4.5 ActivityStack.startActivityLocked
现在这里就是执行栈操作,并且将栈跟Window进行关联。
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
···
// 上面省略的部分就是将当前Stack和Window进行关联
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
4.6 ActivityStackSupervisor .startSpecificActivityLocked
这里就是关键的一步了, 如果当前要启动的Activity进程已经起来了,那么就直接启动Activity
否则就调用AMS启动进程。
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, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
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, false, true);
}
4.7 AMS.startProcessLocked
这里主要三个任务:
- 执行检查,看当前包是否被冻结了,如果被冻结,那么就无法启动
- 启动Process
- 发送一个handler消息,用来定时检查当前Activity是否启动超时
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
try {
try {
if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
// This is caught below as if we had failed to fork zygote
throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
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);
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (app.isolated) {
mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
}
mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
checkTime(startTime, "startProcess: done updating battery stats");
synchronized (mPidsSelfLocked) {
ProcessRecord oldApp;
// If there is already an app occupying that pid that hasn't been cleaned up
if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
// Clean up anything relating to this pid first
Slog.w(TAG, "Reusing pid " + startResult.pid
+ " while app is still mapped to it");
cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
checkTime(startTime, "startProcess: done updating pids map");
} catch (RuntimeException e) {
// XXX do better error recovery.
app.setPid(0);
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
4.8 Process.start
这里就是第二次跨进程调用了 ,但是这里这一次跨进程通信用的就是Socket,并不是Binder了。
SystemServer 进程 ----> Zygote 进程
Process.start方法可以说是一个关键的步骤 这里就是通过Process 来用 Socket 跟Zygote进程进行通信, 通过socket命令,来执行进程的Fork。
这里就可以看到包括SystemServer进程,Android系统中所有的进程都是 zygote进程孵化而来, 这也就是 zygote 名字准确性的体现。
这里涉及到Zygote进程fork 进程,以及Socket通信就不在往下了,感兴趣的可以继续,下面列出几个相关类:
ZygoteInit, LocalSocket,LocalSocketImpl
值得一提的是 在Linux中所有事件都是通过文件描述符来传递的, 因此Socket 其实也是基于文件描述符的。
4.9 ActivityThread启动
当Zygote接受Socket命令,fork一个进程之后,就走到 ActivityThread.main()方法 这里具体的 从4.8 ——> 4.9的更具体的细节我还没搞懂。
public static void main(String[] args) {
Environment.initForCurrentUser(); //这里也是执行关键的一步,就是给当前应用创建 文件用户操作文件夹
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper(); //准备主线程 也就是Actiivty运行的looper
ActivityThread thread = new ActivityThread();
thread.attach(false); //这里也是一个关键地方 这里一次 IApplicationThread绑定
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
ActivityThread.attach()
在Attach方法中,也进行了一些关键处理,
- 将ApplicationThread 作为一个 Server注册到AMS中,这样 AMS就可以和当前应用进行通信了
- RuntimeInit.setApplicationObject 这一句也是关键代码,这里就涉及到 APPCrash的处理了
- 添加GC 回调,出现内存不足时回收内存
- 向ViewRootImpl中注册 Configchange的回调
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try { //这里又是一次跨进程调用了
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {
}
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
4.10 AMS.attachApplication
到这里,目标APP的进程已经起来了,然后APP又会反过来将自己的Server注册到AMS中,
这样AMS就可以继续执行我们最初的目标,StartActivity。
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); // 之前有发送进程启动超时的检查消息,这里已经启动成功,所以进行移除
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; //进行contentProvider的 解析APP中的ContentProvider
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
try {
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//这里也是一个关键步骤,又进行了一次跨进程Binder调用, 将事件回调给APp进程,进行APPlicaiton创建
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
return false;
}
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
// See if the top visible activity is waiting to run in this process...
//继续我们未完成的事业,去启动Actiivty。
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// Find any services that should be running in this process...
//继续我们未完成的事业,去启动Service
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// Check if a next-broadcast receiver is in this process...
// 继续我们未完成的事业,去进行广播接收
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it 'bad'
Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
badApp = true;
}
}
// Check whether the next backup agent is in this process...
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
"New app is backup target, launching agent for " + app);
ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
badApp = true;
}
}
if (badApp) {
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
4.11 AMS 事件回调给Application
-
先看bindApplication //这里进行了一次跨进程, 然后跨线程调用
AMS --> Applicaiton 跨进程
Applicaton binder线程 ----> ActivityThread 线程
private void handleBindApplication(AppBindData data) { //设置时区 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24)); // 创建 Instrumentation if (data.instrumentationName != null) { InstrumentationInfo ii = null; try { ii = appContext.getPackageManager(). getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { } if (ii == null) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = ii.nativeLibraryDir; mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; instrApp.splitSourceDirs = ii.splitSourceDirs; instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; instrApp.dataDir = ii.dataDir; instrApp.nativeLibraryDir = ii.nativeLibraryDir; LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); //创建ContextImpl ContextImpl instrContext = ContextImpl.createAppContext(this, pi); try { java.lang.ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection); } else { mInstrumentation = new Instrumentation(); } // 这里 如果设置了标志位,大内存应用,进行一次清理 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); } else { dalvik.system.VMRuntime.getRuntime().clampGrowthLimit(); } // 创建Application try { Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; if (!data.restrictedBackupMode) { List<ProviderInfo> providers = data.providers; if (providers != null) { //创建ContentProvider对象 installContentProviders(app, providers); mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } } try { mInstrumentation.onCreate(data.instrumentationArgs); } //这里 通过Instrumentation 去调用Application的onCreate方法,可以看道Contentprovider先于Application onCreate调用调用 try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { } } finally { StrictMode.setThreadPolicy(savedPolicy); } }
-
然后看 performLaunchActivity,这里performLaunch 其实也是一次跨进程调用,ActivityThread已经创建 ActivityStackSuperversior 通过持有的 ActivityThread对象,跨进程调用一次,将调用 ActiivtyThread.handleLaunchActivity
AMS在跨进程调用,使当前进程Application创建之后,,就回到我们之前的目的了,启动一个Activity。
```java
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
```
-
重新回到 ActivityStackSupervisor
遍历Display, 然后选出display中的Stack, 选中Stack如果没有要启动的Activity,那么就重新进入Activity创建流程
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } 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; } } } } } return didSomething; }
-
进入ActivityStackSupervisor.realStartActivityLocked
这里又是一次跨进程调用, 使用当前绑定的ApplicationThread来主动启动Activity,之后就进入我们的Activity启动流程了。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { final ActivityStack stack = task.stack; try { if (app.thread == null) { throw new RemoteException(); } List<ResultInfo> results = null; List<ReferrerIntent> newIntents = null; if (andResume) { app.hasShownUi = true; app.pendingUiClean = true; } app.forceProcessStateUpTo(mService.mTopProcessState); //这里就用绑定的ApplicationThread对象来进行跨进程调用 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); } catch (RemoteException e) { if (r.launchFailed) { mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } app.activities.remove(r); throw e; } return true; }
接下来的流程就是执行Actiivty的创建,执行生命周期了。 我们之后接着分析。
网友评论