activity的启动流程(Android2.2源码)
1.当我们调用startActivity方法实际调用的是activity的startActivityForResult
@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);
}
}
因为activity继承于Context,所以他重写的Contex的startActivity方法,startActivityForResult方法最终调用的是
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
throws IntentSender.SendIntentException {
if (mParent == null) {
startIntentSenderForResultInner(intent, requestCode, fillInIntent,
flagsMask, flagsValues, this);
} else {
mParent.startIntentSenderFromChild(this, intent, requestCode,
fillInIntent, flagsMask, flagsValues, extraFlags);
}
}
private void startIntentSenderForResultInner(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, Activity activity)
throws IntentSender.SendIntentException {
try {
String resolvedType = null;
if (fillInIntent != null) {
resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
}
int result = ActivityManagerNative.getDefault()
.startActivityIntentSender(mMainThread.getApplicationThread(), intent,
fillInIntent, resolvedType, mToken, activity.mEmbeddedID,
requestCode, flagsMask, flagsValues);
if (result == IActivityManager.START_CANCELED) {
throw new IntentSender.SendIntentException();
}
Instrumentation.checkStartActivityResult(result, null);
} catch (RemoteException e) {
}
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;
}
}
我们可以看到他执行了Instrumentation的execStartActivity方法,又传递给了Instrumentation,我们看看Instrumentation的这个方法
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<N; 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;
}
这里可以看到他又调用了ActivityManagerNative的startActivity方法又转接到ActivityManagerNative,这里需要说明下checkStartActivityResult这个方法我们看这个方法的源码
private static void checkStartActivityResult(int res, Object intent) {
if (res >= IActivityManager.START_SUCCESS) {
return;
}
switch (res) {
case IActivityManager.START_INTENT_NOT_RESOLVED:
case IActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case IActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException(
"FORWARD_RESULT_FLAG used while also requesting a result");
case IActivityManager.START_NOT_ACTIVITY:
throw new IllegalArgumentException(
"PendingIntent is not an activity");
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
是不是很熟悉的异常,这个方法就是检查当前的activity一些配置信息是否正确,接下来我们看下ActivityManagerNative这这个类,这个类实现了Binder对象,他通过调用getDefault方法得到返回的是ActivityManagerService对象所以最终调用的是ActivityManagerService的startActivity方法而ActivityManagerService是ActivityManagerNative的子类由于他们在不同的进程里面所以要是使用BInder来获取对象实例.这里用到了远程代理,详细解释请看这篇文章,https://www.cnblogs.com/bastard/archive/2012/05/25/2517522.html,我们看看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) {
return startActivityMayWait(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, null, null);
}
public final WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug) {
WaitResult res = new WaitResult();
startActivityMayWait(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, res, null);
return res;
}
private 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) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
final boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
// Collect information about the target of the Intent.
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
ActivityThread.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
} catch (RemoteException e) {
aInfo = null;
}
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
// user navigates back to this point in the history, we should
// always restart the exact same activity.
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't debug things in the system process
if (debug) {
if (!aInfo.processName.equals("system")) {
setDebugApp(aInfo.processName, true, false);
}
}
}
synchronized (this) {
int callingPid;
int callingUid;
if (caller == null) {
callingPid = Binder.getCallingPid();
callingUid = Binder.getCallingUid();
} else {
callingPid = callingUid = -1;
}
mConfigWillChange = config != null && mConfiguration.diff(config) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG,
"Starting activity when config will change = " + mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
int res = startActivityLocked(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, callingPid, callingUid,
onlyIfNeeded, componentSpecified);
if (mConfigWillChange) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG,
"Updating to new configuration after starting activity.");
updateConfigurationLocked(config, null);
}
Binder.restoreCallingIdentity(origId);
if (outResult != null) {
outResult.result = res;
if (res == IActivityManager.START_SUCCESS) {
mWaitingActivityLaunched.add(outResult);
do {
try {
wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
} else if (res == IActivityManager.START_TASK_TO_FRONT) {
HistoryRecord r = this.topRunningActivityLocked(null);
if (r.nowVisible) {
outResult.timeout = false;
outResult.who = new ComponentName(r.info.packageName, r.info.name);
outResult.totalTime = 0;
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
mWaitingActivityVisible.add(outResult);
do {
try {
wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
}
}
}
return res;
}
}
可以看到最终调用到了startActivityMayWait的方法,我们看startActivityLocked方法,resumeTopActivityLocked回复栈顶的activity,如果没有启动过activity就会判断需要启动的Activity所在进程和app已经存在,若存在,直接启动,否则准备创建该进程, 通过startProcessLocked,并通过Socket连接的方式孵化新建了一个Zygote进程创建了ActivityThread类,由于ActivityThread是一个普通的java类,他会执行main方法进行初始化,而所以启动activity的消息执行者就是ActivityThread中的Handler对象,通过ActivityThread的performLaunchActivity()方法完成了Activity的创建和启动过程,,还有Application的创建,
总结:
- 如果通过 Launcher 启动应用时,点击应用图标后,Launcher 调用 startActivity() 启动应用。
- Launcher Activity 最终调用Instrumentation 的 execStartActivity 来启动应用。
- Instrumentation 调用 ActivityManagerProxy 对象的 startActivity 方法启动 Activity,实际是ActivityManagerService 的方法,通过远程代理,binder通信
- 实际是ActivityManagerService的startActivity进过一系列的天剑判断最终调用到resumeTopActivityLocked这个方法
- 由于是从 Launcher 启动所以他会通过socket 发送给 zygote 进程进行创建当前app的ActivityThread 类
- 如果当前activitty在后台会直接调起当前activity
- zygote 进程孵化出新的应用进程后,会执行ActivityThread 类的 main() 方法。在该方法里会先准备好 Looper 和消息队列,然后调用 attach() 方法将应用进程绑定到 ActivityManagerService,然后进入loop 循环,不断地读取消息队列里的消息,并分发消息。
- ActivityManagerService 保存应用进程的一个代理对象,然后 ActivityManagerService 通过代理对象通知应用进程创建入口 Activity 的实例,并执行它的生命周期函数
- 所有的activitry的各种生命周期方法都是通过ActivityThread这个类的Handel对象分发到Instrumentation对象执行响应的逻辑