ソース分析:Activityの起動プロセス(1)
14577 ワード
Activity#startActivityForResult
ActivityのstartActivityメソッドから解析を開始します.このメソッドにはいくつかのリロード方法がありますが、最終的にはstartActivity ForResultメソッドが呼び出されます.このメソッドは次のように実現されます. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) { //
//...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options); // Instrumentation execStartActivity (exec execute , )
//...
} else {
//...
}
}
InstrumentationのexecStartActivityメソッドを見てみましょう
Instrumentation#execStartActivity(API25)
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) { //
//...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options); // Instrumentation execStartActivity (exec execute , )
//...
} else {
//...
}
}
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//...
try {
//...
// Activity
int result = ActivityManagerNative.getDefault() //ActivityManagerNative.getDefault() IActivityManager
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// ,
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManagerNative.getDefault()
static public IActivityManager getDefault() {
return gDefault.get();
}
gDefaultの定義は次のとおりです.
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
Singletonは、getメソッドを最初に呼び出すとcreateメソッドでオブジェクトを作成し、後続の呼び出しでは前に作成したオブジェクトを直接返します.
Instrumentation#execStartActivity(API26)
API 26では、Activityを実際に起動するコードがいくつか変更されています. //ActivityManager.getService() IActivityManager
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
ActivityManager.getService()
ActivityManagerを見てgetService()は何を返しますか? public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// ,Context.ACTIVITY_SERVICE = "activity";
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
高低バージョンは、サービス側(システムプロセス)のAMSのIBinderオブジェクトを先に取得し、得られたIBinderオブジェクトからIActivityManager(システムプロセスのAMSのappプロセスのbinderエージェント)を生成する
ActivityManagerService#startActivity
実装はバージョンによって異なりますが、最終的にはIActivityManagerインタフェースオブジェクトが返され、IActivityManagerインタフェースの実装クラスはAMSなので、最終的にはAMSのstartActivityメソッドが呼び出されます @Override
public 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());
}
@Override
public 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) {
//...
// 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);
}
//ActivityManager.getService() IActivityManager
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// ,Context.ACTIVITY_SERVICE = "activity";
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
実装はバージョンによって異なりますが、最終的にはIActivityManagerインタフェースオブジェクトが返され、IActivityManagerインタフェースの実装クラスはAMSなので、最終的にはAMSのstartActivityメソッドが呼び出されます
@Override
public 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());
}
@Override
public 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) {
//...
// 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);
}
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
しかしAPI 24では、Activity StackSupervisorは、Activity StartyStarterにおいてstartActivity MayWaitメソッドを除去する.
またいくつかのメソッドを呼び出し続けました
ActivityStarter#startActivityMayWait
//...
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);
//...
return res;
ActivityStarter#startActivityLocked
//...
try {
//...
err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true, options, inTask);
}
//...
return err;
ActivityStarter#startActivityUnchecked
//...
// , dontStart true.
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
if (dontStart) {
//...
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked(); //mSupervisor ActivityStackSupervisor
}
//...
}
Activity StackSupervisorとActivity Stack間の相互ジャンプ
ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
//targetStack ActivityStack
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null); //mFocusedStack ActivityStack
}
return false;
}
Activity StackのresumeTopActivity UncheckedLockedメソッドも呼び出されました
ActivityStack#resumeTopActivityUncheckedLocked
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options); // resumeTopActivityInnerLocked
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
最後に返されるresultの値は、resumeTopActivity InnerLockedメソッドを呼び出すことによって得られます.
ActivityStack#resumeTopActivityInnerLocked
mStackSupervisor.startSpecificActivityLocked(next, true, false);
//mStackSupervisor ActivityStackSupervisor
Activity StackSupervisorのstartSpecificActivity Lockedメソッドも呼び出されました
ActivityStackSupervisor#startSpecificActivityLocked
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 {
//...
// activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
//...
}
}
//...
}
ついに、ここでrealStartActivity Lockedメソッドを呼び出してactivityを本格的に起動しました
API 23と以前のバージョンのいくつかの違い
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
//targetStack ActivityStack
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null); //mFocusedStack ActivityStack
}
return false;
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options); // resumeTopActivityInnerLocked
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
mStackSupervisor.startSpecificActivityLocked(next, true, false);
//mStackSupervisor ActivityStackSupervisor
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 {
//...
// activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
//...
}
}
//...
}
ActivityStackSupervisor#startActivityMayWait
ここでのロジックはAPI 24バージョンと同じですが、Activity StackSupervisorクラスのstartActivity Lockedメソッドが呼び出されます
//...
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
//...
return res;
ActivityStackSupervisor#startActivityLocked
//...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
//...
return err;
ここではまたstartActivity UncheckedLockedメソッドを呼び出し続けます(API 24の名前とは違いますがパラメータは同じです)
ActivityStackSupervisor#startActivityUncheckedLocked
//
if (doResume) {
targetStack.resumeTopActivityLocked(null, options);
}
if (doResume) {
targetStack.resumeTopActivityLocked(null); //targetStack ActivityStack
}
Activity StackのresumeTopActivity Lockedメソッドの呼び出しを続行
ActivityStack#resumeTopActivityLocked
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
この方法はAPI 24以降のresumeTopActivity UncheckedLocked方法の実装と同じであり,名前が異なるだけで,その後の呼び出しはAPI 24以降と同じであることがわかる.