调用栈如下
ActivityManagerService.java
public void systemReady(final Runnable goingCallback) 传入goingCallback = null,
ActivityStack.java
final boolean resumeTopActivityLocked(ActivityRecord prev) 传入 null
ActivityRecord next = topRunningActivityLocked(null); //判断有没有Activity在运行。
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
if (mMainStack) {
return mService.startHomeActivityLocked();
}
}
mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
null, null, 0, 0, 0, false, false, null);
然后是
ActivityStack.java 中的
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType,
Uri[] grantedUriPermissions,
int grantedMode, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, boolean onlyIfNeeded,
boolean componentSpecified, ActivityRecord[] outActivity)
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);
}
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();
}
进程启动的方法
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
if (app.pid > 0 && app.pid != MY_PID) {
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
app.pid = 0;
}
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"startProcessLocked removing on hold: " + app);
mProcessesOnHold.remove(app);
updateCpuStats();
System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
mProcDeaths[0] = 0;
try {
int uid = app.info.uid;
int[] gids = null;
try {
gids = mContext.getPackageManager().getPackageGids(
app.info.packageName);
} catch (PackageManager.NameNotFoundException e) {
Slog.w(TAG, "Unable to retrieve gids", e);
}
if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
&& mTopComponent != null
&& app.processName.equals(mTopComponent.getPackageName())) {
uid = 0;
}
if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
&& (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
uid = 0;
}
}
int debugFlags = 0;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
// Also turn on CheckJNI for debuggable apps. It's quite
// awkward to turn on otherwise.
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
// Run the app in safe mode if its manifest requests so or the
// system is booted in safe mode.
if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
Zygote.systemInSafeMode == true) {
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
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);
BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
synchronized (bs) {
if (bs.isOnBattery()) {
app.batteryStats.incStartsLocked();
}
}
EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
if (app.persistent) {
Watchdog.getInstance().processStarted(app.processName, startResult.pid);
}
StringBuilder buf = mStringBuilder;
buf.setLength(0);
buf.append("Start proc ");
buf.append(app.processName);
buf.append(" for ");
buf.append(hostingType);
if (hostingNameStr != null) {
buf.append(" ");
buf.append(hostingNameStr);
}
buf.append(": pid=");
buf.append(startResult.pid);
buf.append(" uid=");
buf.append(uid);
buf.append(" gids={");
if (gids != null) {
for (int gi=0; gi<gids.length; gi++) {
if (gi != 0) buf.append(", ");
buf.append(gids[gi]);
}
}
buf.append("}");
Slog.i(TAG, buf.toString());
app.pid = startResult.pid;
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
} catch (RuntimeException e) {
// XXX do better error recovery.
app.pid = 0;
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
Process.java
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int targetSdkVersion,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, targetSdkVersion, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
分享到:
相关推荐
Activity的生命周期分为几个关键状态:创建(onCreate())、启动(onStart())、可见(onResume())、暂停(onPause())、停止(onStop())、销毁(onDestroy())。理解这些状态及其转换对于优化性能和处理内存管理...
首先,我们来谈谈Activity的跳转。在Android中,我们使用Intent对象来启动一个新的Activity。Intent是一种消息传递对象,它可以包含启动Activity所需的数据。创建Intent有两种方式:显式Intent和隐式Intent。显式...
例如,要启动名为`TargetActivity`的新Activity,可以在当前Activity中写入以下代码: ```java Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); ``` 此外,Intent还支持通过...
首先,我们来谈谈Android `Activity`的生命周期。一个`Activity`从创建到销毁经历了一系列的状态变化,这些状态包括:`onCreate()`(创建)、`onStart()`(可见)、`onResume()`(前台活动)、`onPause()`(暂停)、...
当一个Activity被启动或者从不可见状态恢复到可见状态时,`onResume()`会被调用。这个过程可能因为用户按了Home键、接到了电话或者打开了一个新的Activity而中断,但一旦用户返回,`onResume()`将再次被调用,确保...
接下来,让我们谈谈Activity的部署。在Android开发中,部署通常是指将应用打包成APK文件并安装到设备上。这可以通过Android Studio的Build菜单中的Generate Signed Bundle / APK选项来完成。生成签名的APK后,可以...
最后,我们来谈谈回退栈(BackStack)。在Activity与Fragment交互中,回退栈管理着Fragment的添加、替换和移除。当用户点击返回按钮时,系统会按照回退栈的顺序恢复或移除Fragment。了解如何正确地管理回退栈,能够...
1. **创建状态(Created)**:当Activity首次启动或者由于系统原因重新创建时,会调用`onCreate()`方法。在这个阶段,开发者通常会进行布局加载、初始化组件、设置数据绑定等工作。 2. **启动状态(Started)**:`...
其实我们应用启动的时候会启动Application这个类,这个类是在AndroidManifest.xml文件里其实是默认的 android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name...
2. **优化启动Activity**:启动Activity是冷启动的第一步,尽量保持其简洁,避免在启动时执行耗时操作,如网络请求、大数据量的图片加载等。可以考虑使用SplashActivity作为启动页面,专门用于处理启动时的优化工作...
fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观,并且由activity 管理的back stack 中保存些变化。 Fragment
`putExtra()`方法是Intent类的一个成员,用于添加额外的数据到Intent中,以便在启动目标Activity时能够访问这些数据。例如,我们可以传递基本类型(如int、String等)以及Parcelable或Serializable接口实现的对象。 ...
接下来,我们谈谈使用Activity作为弹出窗口的方式。这种方式通常适用于需要一个全屏或者半屏的独立界面,且包含复杂交互的情况。例如,登录窗口、设置界面等。创建一个新Activity,并在主题中设置透明背景,就可以...
3. 添加和替换内部Activity:使用LocalActivityManager的startActivity()和replaceId()方法来启动和替换内部Activity。这两个方法会自动处理Activity的压栈和出栈操作。 虽然ActivityGroup在新的Android版本中已...
了解了如何在`Activity`和`Service`中获取屏幕尺寸后,我们再谈谈Android组件之间的通信。在Android中,`Activity`和`Service`之间的通信通常有以下几种方式: 1. ** Binder **:通过实现`IBinder`接口,`Service`...
将包含过渡动画的Activity设置为默认启动的Activity,然后在`onCreate()`方法中调用`postDelayed()`,将延时时间设置为两秒,这样在启动时会等待两秒后执行后续操作。以下是一个简单的过渡页面布局示例: ```xml ...
当用户需要从一个Activity移动到另一个Activity时,开发者会使用Intent对象来指定目标Activity,并调用startActivity()方法来启动这个过程。Intent不仅可以用来启动Activity,还可以用于启动服务或广播接收器,但在...
Task就像一个堆栈,新启动的Activity会被压入栈顶,成为当前活动的Activity,而用户可以通过返回操作移除栈顶的Activity,使栈底的Activity成为当前活动。Task通常与应用的前台运行状态相对应,用户看到的是一个整体...
例如,当你需要从一个Activity启动另一个Activity时,你会使用显式Intent,并指定目标Activity的ComponentName。 ```java Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity...