2019-02-27 9.0 activity起動フローソース分析
23585 ワード
Android 9.0のソースコードは以前に比べて再構築され、学習の気持ちで9.0でactivityを起動する流れを撫でています.
activityを開くと最終的にこのメソッドが呼び出され、実装されます.
mInstrumentationはactivityライフサイクルを管理するために使用され、具体的にはどこでインスタンス化され、後で分析されます.下を見続ける
ActivityManager.getService()という行コードの役割は、プロセス間呼び出しによるActivity Management Serviceの取得の例です.
最後にActivity Management Servicesに呼び出されるstartActivityメソッドでは、Activity Management Servicesが存在するプロセスと現在のactivityのプロセスは同じではないことに注意してください.
最後にActivity Starterが呼び出されます.Excuteメソッド
一連のジャンプを経てresumeTopActivity InnerLockedメソッドに到達すると、このメソッドは主に3つの部分に分けられる:第1、スタックトップactivityを呼び出すonPauseメソッド第2、タスクスタックに基づいてactivityを直接呼び出すかどうかを判断するonNewIntentメソッド第3、新しいactivityを起動してまず第1の部分を分析する
前述の解析から、IApplicationThreadのインスタンスオブジェクトはActivity Threadの内部クラスApplicationThreadオブジェクトであり、AIDLを使用してamsプロセスからactivityプロセスにデータを送信する
Activity ThreadのscheduleTransactionメソッドを呼び出しますが、Activity Threadはこのメソッドを書き換えていないので、親クラスに行って探します
Handlerの動作原理によってmHを知ることができる.sendMessage(msg); あとはmHのhandleMessageメソッドへ
cycleToPathメソッドは、現在がonCreateの最終ステータスがonResumeである場合など、現在のライフサイクルを現在のステータスから最終ステータスにループすることにより、onStartメソッドが自動的にループ実行され、その後、分析を継続するItemが分析される.executeメソッドは、上から伝わるItemがPauseActivity Itemであることがわかります
最終的に一連の呼び出しを経て、activityのonPauseメソッドに進み、ここでactivity起動プロセスの最初のライフサイクルメソッドが終了し、後の2つの部分で、次の分析を行います.
startActivity
activityを開くと最終的にこのメソッドが呼び出され、実装されます.
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
public void startActivity(Intent intent, @Nullable Bundle options) {
// Bundle , else
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
// startActivityForResult
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
Instrumentation.ActivityResult ar =
// mInstrumentation activity
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
//......
}
mInstrumentationはactivityライフサイクルを管理するために使用され、具体的にはどこでインスタンス化され、後で分析されます.下を見続ける
//Instrumentation
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// IApplicationThread AIDL
// ActivityThread ApplicationThread
// service ams
IApplicationThread whoThread = (IApplicationThread) contextThread;
//.........
try {
// ams ActivityManagerService startActivity
int result = ActivityManager.getService()
.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;
}
ActivityManager.getService()という行コードの役割は、プロセス間呼び出しによるActivity Management Serviceの取得の例です.
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
// Singleton
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// ActivityManagerService
// android AIDL
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
// ,
//
public abstract class Singleton {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
最後にActivity Management Servicesに呼び出されるstartActivityメソッドでは、Activity Management Servicesが存在するプロセスと現在のactivityのプロセスは同じではないことに注意してください.
// ActivityManagerService
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());
}
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) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
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,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// ,
//obtainStarter ActivityStarter
// ActivityStarter.setMayWait
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
// ActivityStarter
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
ActivityStarter setMayWait(int userId) {
// mayWait true
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
最後にActivity Starterが呼び出されます.Excuteメソッド
int execute() {
try {
// mayWait true
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
} finally {
onExecutionComplete();
}
}
private 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 globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
//.......
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
//.......
return res;
}
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
//.....
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup);
return getExternalResult(mLastStartActivityResult);
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
//.......
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
//.....
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
//.......
return result;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
//.........
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mService.mWindowManager.executeAppTransition();
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
//
// ,
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
//
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
try {
//
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
一連のジャンプを経てresumeTopActivity InnerLockedメソッドに到達すると、このメソッドは主に3つの部分に分けられる:第1、スタックトップactivityを呼び出すonPauseメソッド第2、タスクスタックに基づいてactivityを直接呼び出すかどうかを判断するonNewIntentメソッド第3、新しいactivityを起動してまず第1の部分を分析する
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//.....
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
// ResumedActivity ,
pausing |= startPausingLocked(userLeaving, false, next, false);
}
//........
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
//.....
if (prev.app != null && prev.app.thread != null) {
try {
//9.0
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
}
}
//....
}
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ClientTransactionItem callback) throws RemoteException {
// ClientTransaction
final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
callback);
//
scheduleTransaction(clientTransaction);
}
private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
IBinder activityToken, @NonNull ClientTransactionItem callback) {
// ClientTransaction , callback add ClientTransaction
final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
clientTransaction.addCallback(callback);
return clientTransaction;
}
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
// schedule
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
// ClientTransaction
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
// mClient ClientTransaction IApplicationThread
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
前述の解析から、IApplicationThreadのインスタンスオブジェクトはActivity Threadの内部クラスApplicationThreadオブジェクトであり、AIDLを使用してamsプロセスからactivityプロセスにデータを送信する
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// ActivityThread scheduleTransaction
ActivityThread.this.scheduleTransaction(transaction);
}
}
Activity ThreadのscheduleTransactionメソッドを呼び出しますが、Activity Threadはこのメソッドを書き換えていないので、親クラスに行って探します
//ActivityThread ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
Handlerの動作原理によってmHを知ることができる.sendMessage(msg); あとはmHのhandleMessageメソッドへ
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// TransactionExecutor execute
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
// TransactionExecutor
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
public void executeCallbacks(ClientTransaction transaction) {
final List callbacks = transaction.getCallbacks();
// onPause callbacks
if (callbacks == null) {
// No callbacks to execute, return early.
return;
}
//......
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
log("Resolving lifecycle state: " + lifecycleItem);
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
//
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Item execute Item PauseActivityItem
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
cycleToPathメソッドは、現在がonCreateの最終ステータスがonResumeである場合など、現在のライフサイクルを現在のステータスから最終ステータスにループすることにより、onStartメソッドが自動的にループ実行され、その後、分析を継続するItemが分析される.executeメソッドは、上から伝わるItemがPauseActivity Itemであることがわかります
// PauseActivityItem
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
// client ActivityThread ActivityThread.handlePauseActivity
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
//ActivityThread
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
// performPauseActivity
performPauseActivity(r, finished, reason, pendingActions);
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
mSomeActivitiesChanged = true;
}
}
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
if (r.paused) {
//........
performPauseActivityIfNeeded(r, reason);
//...........
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
//......
// mInstrumentation activity
mInstrumentation.callActivityOnPause(r.activity);
//......
}
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
// activity onPause
onPause();
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
}
最終的に一連の呼び出しを経て、activityのonPauseメソッドに進み、ここでactivity起動プロセスの最初のライフサイクルメソッドが終了し、後の2つの部分で、次の分析を行います.