ActivityManagerServiceの起動プロセス
前書き
この記事では、モバイルデスクトップ(ランチャー)が未起動のアプリのアイコンをクリックしてからアプリの起動が完了する(コールドスタート)までのプロセスについて説明します。
全体的なプロセス
Launcher、AMS、Zygote、およびアプリはすべて異なるプロセスにあり、プロセス間で通信する必要があります。
ユーザーがランチャーのアプリアイコンをクリックすると、ランチャーはAMSに通知します。ターゲットアプリが開始されていない場合(コールドスタート)、AMSはZygoteにソケットを介してプロセスを作成するよう通知し、Zygoteは開始するアプリプロセスをフォークします。
アプリがHomeActivityを開きたいと思った直後に、AMSと対話する必要があります
- app-> AMS:AMSは起動時にServiceManagerに登録されているため、アプリはgetServiceを呼び出すことでServiceManagerからAMSプロキシクラスIActivityManager(クライアント)を取得できます。アプリは、IActivityManagerを介してAMS(サーバー)メソッドを呼び出します。
- AMS-> app:AMSは、IApplicationThread(サーバー)と呼ばれるIBinderを準備します。アプリプロセスが開始されると、IApplicationThreadのattachApplicationメソッドが呼び出され、アプリのプロキシクラスApplicationThread(クライアント)がパラメーターとしてAMSに渡されます。AMSは、ApplicationThreadメソッドを呼び出してアプリを制御できます。
IApplicationThreadの実装クラスは、ActivityThreadの内部クラスApplicationThreadです。
フローチャートを読んだ後、シーケンス図を見てみましょう
。図の4はattachApplicationプロセスであり、アプリのプロキシクラスApplicationThreadがAMSに渡されます。
図の5は、AMSが何らかの処理を行った後、アプリのHomeActivityがアプリのプロキシクラスApplicationThreadを介して開始されたものです。
関連するデータ構造
ソースコードを見る前に、いくつかの重要なデータ構造を理解する必要があります
ProcessRecord(プロセス)
最初のタイプのデータ:アイデンティティを説明するデータ
- ApplicationInfo info:AndroidManifest.xmlで定義されているアプリケーション情報
- 孤立したブール:それは孤立したプロセスですか
- int uid:プロセスuid
- int userId:これはandroidによって作成されたマルチユーザーシステムIDです。Windowsが多くのユーザーにログインできるように、androidも同様のマルチユーザーを実現したいと考えています。
- 文字列processName:プロセス名。デフォルトではパッケージ名です。
- UidRecord uidRecord:使用されたuidを記録します
- IApplicationThreadスレッド:これは非常に重要です。これはApplicationThreadのクライアントです。AMSはこのオブジェクトを使用して非同期メッセージをapkプロセスに送信します(4つの主要コンポーネントのメッセージを管理します)。したがって、このオブジェクトが空でない場合にのみ、apkプロセスを表します。使用する準備ができて
- int pid:プロセスのpid
- 文字列procStatFile:procディレクトリ内の各プロセスにはpidという名前のディレクトリファイルがあります。このディレクトリにはプロセスの詳細情報が記録されます。ディレクトリとディレクトリ内のファイルはカーネルによって作成されます。procはカーネルファイルシステムであり、procはプロセスです。略語、関連する目的は、プロセスカーネル情報をエクスポートすることです
- int [] gids:gidグループ
- ComplianceInfo compat:互換性情報
- 文字列requiredAbi:abi情報
- 文字列instructionSet:命令セット情報
2番目のタイプのデータ:プロセスのコンポーネントを説明するデータ
- pkgList:プロセスで実行されているパッケージ
- ArraySet pkgDeps:プロセスが依存するパッケージ
- ArrayListアクティビティ:プロセスによって開始されたすべてのアクティビティコンポーネントのレコードテーブル
- ArraySetサービス:プロセスによって開始されたすべてのサービスコンポーネントのレコードテーブル
- ArraySet runningServices:実行(実行)はどのように定義されていますか?最初に明確にする必要があるのは、システムがコンポーネントをどのように制御するかです。apkプロセスにメッセージを送信すると、apkプロセスがメッセージを処理し、レポートが完了します。これは、完全な実行プロセスとして定義されます。したがって、実行は、メッセージを送信してからレポートが完了するまでの期間として定義されます。
- ArraySet接続:バインディングサービスクライアントレコードテーブル
- ArraySetレシーバー:ブロードキャストレシーバーのレコードテーブル
- ContentProviderRecord pubProviders:pubは公開を意味します。ContentProviderは、使用する前にインストールしてからシステム(AMS)に公開する必要があります。インストールとは、apkプロセスでContentProviderサブクラスをロードし、データベースの作成を初期化するなどのプロセスを指します。 ContentProviderのバインダークライアントがAMSに登録されている
- ArrayList conProviders:ContentProviderを使用したクライアントレコードテーブル
- BroadcastRecord curReceiver:現在のプロセスによって現在実行されているブロードキャスト。このセクションでは、上記のコンポーネント情報は簡単な説明であり、コンポーネント管理を個別に分析するときに詳細に紹介します。
さらに、プロセスの状態を説明するデータ、pssに関連するデータ、時間に関連するデータ、クラッシュとanrに関連するデータ、計測に関連するデータ、電源情報とデバッグ情報などがあります。
ActivityRecord
アクティビティはAMS内のActivityRecordの形式で存在し、ActivityとActivityRecordは1対1で対応しています。
- ProcessRecordアプリ:どのプロセスが実行されているか
- TaskRecordタスク:どのタスクが実行されているか
- ActivityInfo情報:アクティビティ情報
- int mActivityType:アクティビティタイプ
- ActivityState状態:アクティビティ状態
- ApplicationInfo appInfo:実行中のアプリ
- ComponentName realActivity:コンポーネント名
- 文字列packageName:包名
- 文字列processName:プロセス名
- int launchMode:起動モード
- int userId:アクティビティが実行されているユーザーID
mActivityType
- APPLICATION_ACTIVITY_TYPE:一般的なアプリケーションタイプ
- HOME_ACTIVITY_TYPE:デスクトップタイプ
- RECENTS_ACTIVITY_TYPE:最近のタスクタイプ
ActivityState
- 初期化
- 再開:回復
- 一時停止
- 一時停止:一時停止
- 停止
- 停止:停止
- 仕上げ
- 破壊
- 破壊された:破壊された
ActivityRecordは、ActivityStarterのstartActivityメソッドで作成されます
TaskRecord
タスクスタックTaskRecordは、ActivityRecordを格納するためにArrayListを内部的に維持します。
- ActivityStackスタック:スタックは現在属している
- ArrayList mActivities:現在のタスクのすべてのアクティビティのリスト
- int taskId
- 文字列アフィニティ:ルートアクティビティ、つまりタスクの最初のアクティビティのアフィニティを指します
- int mCallingUid
- 文字列mCallingPackage:呼び出し元のパッケージ名
TaskRecordは、ActivityStarterのsetTaskFromReuseOrCreateNewTaskに作成されます。
ActivityStack
ActivityStackは、TaskRecordを管理するためにArrayListを内部的に維持します。
電話機には3つの仮想ボタンがあります。右端の四角いボタンを押すと、最新のタスクが表示されます。最新のタスクはActivityStackであり、デスクトップアプリケーションもActivityStackです。
ArrayListのmTaskHistory //すべてのセーブタスクリスト
のArrayList mStacks; //リストのすべてのスタック
最終int型mStackId;
int型mDisplayId;
ActivityRecord mPausingActivity //」のRE PAUSE
ActivityRecord mLastPausedActivity
ActivityRecord mResumedActivity //すでにRESUMED
ActivityRecord mLastStartedActivity
mResumedActivity状態の全ての前景スタック== RESUMED 、これはallResumedActivitiesCompleteを意味し、現時点ではmLastFocusedStack = mFocusedStack;
ActivityStackSupervisor
ActivityStackSupervisorは、その名前が示すように、ActivityStackを管理するために使用されます
- ActivityStack mHomeStack:デスクトップスタック
- ActivityStack mFocusedStack:現在のフォーカススタック
- ActivityStack mLastFocusedStack:切り替え
- SparseArray mActivityDisplays:displayId是キー
- SparseArray mActivityContainers:mStackId是キー
- ホームのスタックIDは0に等しい、つまりHOME_STACK_ID = 0;
ActivityStackSupervisor内には2つの異なるActivityStackオブジェクトがあります。mHomeStackとmFocusedStackで、さまざまなタスクを管理するために使用されます。
ActivityStackSupervisorには、ActivityStackオブジェクトを作成するためのメソッドが含まれています。
AMSが初期化されると、ActivityStackSupervisorオブジェクトが作成されます
詳細なプロセス
- インストルメンテーション:ライフサイクルとアクティビティの開始を管理します
- ActivityManagerProxy:AMSプロキシオブジェクト
- ApplicationThreadProxy:APPを開始するプロキシオブジェクト
- ApplicationThreadはバインダーサービスであり、メインスレッドではありません
9番目のステップは、子スレッドApplicationThreadからメインスレッドActivityThreadまで、Handlerを介してスレッド間で通信することです。