ActivityManagerServiceプロセス
11237 ワード
Activity起動プロセス
目的:
一、activityのライフサイクル管理とAMSの関係を整理する
1、LauncherはAMSにactivityを起動するように通知する。
Launcherでは、アプリケーションでactivityを開くstartActivity Safely()---->startActivity()、プログラム内で起動する場合はActivityのstartActivity()を直接呼び出し、起動されたactivityのパラメータはintentに含まれ、intentのパラメータは自xmlファイル、----->startActivity ForResult()------>mInstrumentation.MixecStartActivity(this,mMainThread.getApplicationThread()、mToken,this,intent,requestCode,options)は、アプリケーションとシステムとの相互作用を監視するためのInstrumentationである、mMainThreadはActivity Threadクラスのインスタンスである.getApplicationThread()内部のApplicationThreadのBinderオブジェクトを取得するために使用されます(ここで疑問がありますか?);---->ActivityManagerNative.getDefault() .startActivity(), .getDefault()は、AMSのプロキシオブジェクト「activity」をServerManagerから取得します.コードは次のとおりです.
//ActivityManagerNative.java
private static final Singleton gDefault = new Singleton() {
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;
}
};
次に、彼のメソッドstartActivity()を呼び出して、AMSに対応するActivityを起動するように通知します.ここではbinder通信です.
startActivitySafely() AMS: Launcher activity
|
startActivity() ----------> AMS Stub startActivity(), ActivityManagerService.java
これでLauncherで一旦終了です!つまりLauncherプロセスは-->AMSにactivityを起動するように要求します.具体的にはどのactivityですか.intentを見てください.
2、AMSは起動するmainactivityを保存し、AMSはLauncherがAMSに送信するbinderメッセージ:START_を処理するACTIVITY_TRANSACTION
startActivity() ------->AMS
|
startActivityAsUser() ------->AMS
|
mStackSupervisor.startActivityMayWait() ------->ActivityStackSupervisor.java
|
startActivityLocked() ------->ActivityStackSupervisor.java
|
startActivityUncheckedLocked()
|
resumeTopActivitiesLocked(targetStack, null, options) ----->ActivityStack.java
|
startPausingLocked() ----->ActivityStack.java
|
prev.app.thread.schedulePauseActivity() ----->ActivityStack.java Proxy
|
...binder... AMS--->Launcher: AMS Launcher Pause
|
schedulePauseActivity() ------>ActivityThread.java Stub
//ActivityThread.java
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
configChanges);
}
3、LauncherがPause要求を受け取った後の動作は、AMSに返信する(AMSのproxy経由)
schedulePauseActivity() ------>ActivityThread.java Stub
|
sendMessage() ------>ActivityThread.java
|
handleMessage(Message msg) ------>ActivityThread.java
|
handlePauseActivity()
|
performPauseActivity(token, finished, r.isPreHoneycomb()); ------>ActivityThread.java
ActivityManagerNative.getDefault().activityPaused(token) ------>ActivityThread.java AMS proxy
|
...binder... Launcher--->AMS : Launcher AMS,Launcher Pause
|
activityPaused(token) ------>AMS Stub
質問:
4、AMSでLauncherからのPaused通信要求を処理し、対応する処理を行う
activityPaused(token) ------>AMS Stub
|
activityPausedLocked() ------>ActivityStack.java
|
completePauseLocked(true)
|
finishCurrentActivityLocked()
|
resumeTopActivityLocked()
|
resumeTopActivityInnerLocked()
|
startSpecificActivityLocked() ------->ActivityStackSupervisor.java
|
startProcessLocked() ------->AMS
|
startProcessLocked() -------> , AMS ( )
//AMS startProcessLocked()
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!");
|
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
}
|
zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
|
zygote , PID AMS, ActivityThread main 。
これで、AMSはProcessクラスを呼び出して新しいアプリケーションを作成します.また,このプロセスのエントリ関数はmain関数であり,次は新しいアプリケーションプロセスの作業である.
5、新しいアプリケーションが起動すると、AMSに起動完了したプロセス間通信が送信されます。
main() ------->ActivityThread.java
|
Looper.prepareMainLooper() -------> ,
ActivityThread thread = new ActivityThread() ActivityThread
attach(boolean system) ------->ActivityThread.java
|
final IActivityManager mgr = ActivityManagerNative.getDefault();// AMS proxy
mgr.attachApplication(mAppThread) ----->AMS proxy, IActivityManager
|
...binder... ActivityThread--->AMS: APP AMS
|
attachApplication(IApplicationThread thread) ----->AMS Stub
|
Looper.loop()
これで、新しいアプリケーションプロセスが呼び出されます.attach(false)はattach()関数を呼び出してAMSのproxyにプロセス間通信返信ATTACH_を送信するAPPLICATION_TRANSACTION:AMSに新しいアプリケーションが起動したことを伝えます.
6、AMSは、2ステップで保存したMainActivity情報を、4ステップで作成した新しいアプリケーションに送信し、MainActivityを起動できるようにする
attachApplication(IApplicationThread thread) ----->AMS Stub
|
attachApplicationLocked(IApplicationThread thread, int pid) ----->AMS
|
attachApplicationLocked(ProcessRecord app) ----->ActivityStackSupervisor.java
|
realStartActivityLocked(hr, app, true, true) ----->ActivityStackSupervisor.java
|
app.thread.scheduleLaunchActivity() ----->ActivityThread proxy
|
...binder... AMS--->ActivityThread: AMS MainActivity
|
scheduleLaunchActivity() ----->ActivityThread Stub
これで、AMSはプロセス間通信SCHEDULE_をActivity Threadに送信するLAUNCH_ACTIVITY_TRANSACTION
7、アプリケーションで最後の作業を実行する
scheduleLaunchActivity() ----->ActivityThread Stub
|
sendMessage(H.LAUNCH_ACTIVITY, r)
|
handleMessage(Message msg)
|
handleLaunchActivity(r, null)
|
Activity a = performLaunchActivity(r, customIntent)
|
mInstrumentation.callActivityOnCreate(activity, r.state) ------->Instrumentation.java
|
activity.performCreate(icicle)
|
onCreate(icicle) ------>Activity.java
|
protected void onCreate(@Nullable Bundle savedInstanceState)
アプリで引き継いだOnCreate()が呼び出され、最後にActivityオブジェクトactivityが起動しました
注意:
1、mainActivityコンポーネントはLauncherコンポーネントによって起動され、LauncherコンポーネントはまたAMSによってmainActivityを起動するので、3つのプロセス間のbinder通信2、AMS起動はPMSと同様にシステムサーバプロセスで起動され、startBootstrapServices()関数に関連する.3、ActivityManagerServicesもちゃんと整理しなければなりません.java,ActivityManagerNative.java,IActivityManager.JAva間の関係
まとめ、質問:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
// Initialize before creating the activity
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); // launch ResumeActivity
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
}
}
...