Androidの4つの主要コンポーネントのアクティビティ起動プロセスのソースコード実装の詳細な概要
Androidシリーズのブログディレクトリの4つの主要コンポーネントのソースコード実装の詳細な説明:
Androidアプリケーションプロセスの作成プロセス
は、Androidの4つの主要コンポーネントの bindServiceソースコード実装の詳細の秘密を明らかにします。Androidの
4つの主要コンポーネントのアクティビティ起動プロセスソースコード実装の詳細の詳細。Androidの4つの主要コンポーネントのアクティビティ開始プロセスソースコードの実装詳細
(1)
序文
活動開始プロセスの詳しい解説については、ブログを書いていくつもりですが、自信がないからではなく、実は理由があるからといって、自分のスキルが足りないと感じていました!アクティビティの起動には多くのロジックが含まれ、起動プロセスはより複雑です。Androidプロセスの作成、アクティビティでのライフサイクルのスケジューリング、タスクスタックの選択とスケジューリング、AndroidプロセスコミュニケーションバインダーIPCメカニズムおよびナレッジポイントの他の側面!これらの一連のブログのために、私は長い間準備をしており、事前に関与する主要な知識の基礎を築いてきました。
- Android Binderの知識に関しては、Android Binderフレームワークの実装に関する一連のブログを作成しました。AndroidBinderフレームワークの詳細な紹介
- Androidプロセスの作成については、Androidアプリプロセスの作成プロセスについてブログを作成しており、Androidアプリプロセスの作成プロセスについて詳しく紹介しています。
- 同時に、みんなを温めるために、私は事前に意図的にAndroidの4つの主要コンポーネントでサービスを選択し、bindServiceを例としてプロセスを詳細に分析しました。詳細については、Androidの4つの主要コンポーネントのbindServiceソースコード実装の詳細な説明を参照してください。
虽然有了上述如此多的准备,说句心里话写本篇系列博客还是心里非常忐忑,不为别的主要担心自己功力不够,怕写出的东西有纰漏或者错误之处,但是还是硬着头皮往下干了!至少,我是在用心写着!当然如果能帮到小伙们那是最开心不过的了!
- 注意:本篇的介绍是基于Android 7.xx平台为基础的,其中涉及的代码路径如下:
frameworks/base/services/core/java/com/android/server/am/
--- ActivityManagerService.java
--- ProcessRecord.java
--- ActivityRecord.java
--- ActivityResult.java
--- ActivityStack.java
--- ActivityStackSupervisor.java
--- ActivityStarter.java
--- TaskRecord.java
frameworks/base/services/core/java/com/android/server/pm、
--- PackageManagerService.java
frameworks/base/core/java/android/app/
--- IActivityManager.java
--- ActivityManagerNative.java (内部包含AMP)
--- ActivityManager.java
--- AppGlobals.java
--- Activity.java
--- ActivityThread.java(内含AT)
--- LoadedApk.java
--- AppGlobals.java
--- Application.java
--- Instrumentation.java
--- IApplicationThread.java
--- ApplicationThreadNative.java (内部包含ATP)
--- ActivityThread.java (内含ApplicationThread)
--- ContextImpl.java
- 并且在后续的源码分析过程中为了简述方便,会将做如下简述:
ApplicationThreadProxy简称为ATP
ActivityManagerProxy简称为AMP
ActivityManagerService简称为AMS
ActivityManagerNative简称AMN
ApplicationThreadNative简称ATN
PackageManagerService简称为PKMS
ApplicationThread简称为AT
ActivityStarter简称为AS,这里不要和ActivityServices搞混淆了
ActivityStackSupervisor简称为ASS
一. Activity启动的整体概括和前期知识准备
在写该系列博客的时候,无意中看到了一篇微信号的文章我为什么这么讨厌你一行行地讲代码?,其中最后一段话说的很在理!
毎回、私はそのような技術的な記事が非常に痛いのを見る。コードを1行ずつ教えてどういう意味ですか?C言語が理解できませんか?最初に書きたいことについて教えてください。あなたが書いたものの全体的な枠組みは何ですか?コードに関して、いくつかの重要なポイント、関数名、またはフローチャートを教えてもらえますか?私がそれを自分で行うことはできますか?
実行中のアカウントに関する記事が一般に読者にとって役に立たないのはなぜですか?半分の労力で2倍の結果が得られるからです。あなたを読むのに長い時間がかかりましたが、読んだ後、それはまだわかりません。それは、すべての詳細であり、全体的な概要を形成しなかったためです。
はい、この種のブログは多くのことを書いていますが、読者はすべてを持っていると感じますが、何もありません!したがって、この一連のブログでは、主要なコンテキストに焦点を当てて、コードの行ごとの分析を中止します。読者が詳細に興味がある場合は、全体的な知識を明確にし、ゆっくりと深めることができます。最初に本を読み進めてください。増粘理論は発散します!
1.1アクティビティの起動の全体的な概要
Activityの長くて複雑な起動プロセスの分析を正式に開始する前に、まずActivityの起動プロセス全体(例としてコールドスタート)を要約します。これは次の段階に大別できます。
-
ソースエンド・プロセスは、対象の活動を開始するための要求を送信します:1.ソース・エンドを開始活動を開始するには、表示/暗黙の開始要求を
-
system_serverプロセスは、AMSプロセス要求アクティビティによって開始:2。テントターゲットアクティビティ解析を開始するために3 ActivityRecord対応する作成対象アクティビティ4を検索/アクティビティがターゲットに割り当てられているか、タスクのスタック最適作成する。5 .Pauseフォアグラウンドアクティビティ6 .Resume要求対象アクティビティ7. AMSは、zygoteプロセスに、ターゲットアクティビティのプロセスを作成するように要求します。
-
接合子プロセスハンドルはsystem_serverプロセスによって送信された標的活性処理要求ステージを作成するプロセス:8接合子は、ターゲットアクティビティが属するプロセスを作成するために、AMS要求フォークを受け入れる。9.通話が対象プロセスの動作環境を初期化するRuntimeInit 。10.対象プロセスのコールmainメソッドを起動するためにリフレクションを介してメインスレッドをActivityThread目標達成の新時代
-
ターゲットアクティビティプロセスの開始フェーズ:11.ターゲットアクティビティプロセスのルーパーメッセージループを開きます12. ApplicationThreadをsystem_serverプロセスに登録します13.ターゲットプロセスアプリケーションを作成し、そのonCreateメソッドを実行します。
-
標的活性ライフサイクルステージを開く。14.本当にターゲットアクティビティを開始する15反射を介して負荷標的活性を16ターゲットアクティビティのライフサイクル実行17初期化を表示するために準備するターゲットアクティビティウィンドウ
-
ターゲットアクティビティの表示ステージ:18.新しいDecorView 19.新しいViewRootImpl 20.ウィンドウをWMSに追加して表示可能
-
ソース側のアクティビティでの作業の終了:21.ソース側のアクティビティは、onStop()などのロジックを実行します
次の一連のブログでは、上記の概要から始めて、主要なメソッドまたは関数の分析と組み合わせた疑似コードを通じて、アクティビティの起動プロセスの説明を拡張します。リーダーはアクティビティの開始プロセス全体を明確に理解できます。関係するさまざまな細部については、自分で行うかどうかはあなた次第です。
2.アクティビティ開始のための予備知識の準備
アクティビティの起動に関するいくつかの知識を保存しましたが、それでもまだ十分ではないため、アクティビティの起動プロセスに関連する多くの概念を事前に理解しておく必要があります。
2.1アクティビティのコールドスタートとホットスタート
ブログでは、アクティビティのホットスタートとコールドスタートについて言及している人が多いと思いますが、このコンセプトを最初に聞いた人もいます。ここでのホットスタートとコールドスタートは、運転中のホットスタートとコールドスタートとは異なる場合があります。 Androidのアクティビティでのホットとコールドの2つの起動方法の簡単な説明:
2.1.1アクティビティのコールドスタート
アクティビティが開始されると、バックグラウンドでアクティビティに対応するアプリケーションのプロセスはありません。このとき、Androidシステムはアクティビティに対応するプロセスを作成し、アクティビティの作成と表示のプロセスを実行します。このスタートアップメソッドはコールドスタートです。その主な機能はコールドスタートです。システムはzygoteを介してそれに割り当てる新しいプロセスを作成するため、最初にApplicationクラスを作成して初期化し、次にターゲットActivityクラス(一連の測定、レイアウト、描画を含む)を作成して初期化します。最後にインターフェイスに表示されます。
2.1.2アクティビティのホットスタート
ターゲットアクティビティが開始されると、Androidバックグラウンドには、アクティビティの対応するアプリケーションプロセスがあります(例:バックキー、ホームキーを押しますが、アプリケーションは終了しますが、アプリケーションプロセスはバックグラウンドに残ります。タスクリストを入力して表示できます) 、したがって、既存のプロセスの場合、このスタートアップは既存のプロセスからアプリケーションを起動します。このメソッドはホットスタートと呼ばれます。この起動メソッドの最大の特徴は、アプリアプリケーションが新しいプロセスの作成からプロセスの破棄まで一度しか初期化されないため、アプリケーションを作成して初期化する必要がなく、ターゲットアクティビティ(一連の測定、レイアウトを含む)の作成と表示に直接移動する必要がないことです。ドロー)。
2.2アクティビティのライフサイクル
これは、多くの人が最初にAndroidを起動したときに知っておくべき知識ポイント、つまり、アクティビティのライフサイクルであると私は思います。
- protected void onCreate(Bundle savedInstanceState)
- protected void onRestart(…)
- protected void onStart(…)
- 保護されたvoid onResume(…)
- 保護されたvoid onPause(…)
- 保護されたvoid onStop(…)
- 保護されたvoid onDestory(…)
上記は、アクティビティライフサイクルの各期間のコールバックメソッドです。さまざまなメソッドで、さまざまなロジックを実行できます。クラシックダイアグラムは次のとおりです。
2.3アクティビティ表示の開始と暗黙の開始
ご存じのとおり、Androidコンポーネントの起動モードには明示的な呼び出しと暗黙的な呼び出しの2つがあり、これら2つの呼び出し方法は文字通りの意味でよく理解されています。個別に説明しましょう。
2.3.1ディスプレイの起動
明示的な呼び出しでは、開始するコンポーネントを次のように指定する必要があります。
Intent intent = new Intent();
intent.setClass(this,XXXActivity.class);
startActivity(intent);
ここで、表示の開始は、Intentオブジェクトが初期化されるときに開始する必要があるアクティビティのバイトコードを直接参照することであることがわかります。表示の開始の利点は、開始する必要があるアクティビティをインテントフィルターインデックスを実行せずに、Intentオブジェクトによって開始されるアクティビティオブジェクトに直接通知できることです。インターネット上の多くのブログでは、他のプロセスのActivityオブジェクトのバイトコードを取得できないため、他のプロセスのActivityオブジェクトを開始できないことが示されています。このステートメントは正しくないと思います。たとえば、以下に示すように、これは明確なプロセス間起動ではありません。終了プロセスのアクティビティはありますか?
Intent intent=new Intent();
ComponentName cName = new ComponentName("com.android.settings","com.android.settings.Settings$WifiSettingsActivity");
intent.setComponent(cName);
startActivity(intent);
2.3.2暗黙の開始
暗黙的な呼び出しでは、起動するコンポーネントを指定する必要はありませんが、次のようにアクションを通じて一致します。
Intent intent = new Intent();
intent.setAction("xxx.xxx.xxx");
startActivity(intent);
ここでは、暗黙の開始が、アクションを構成することにより、アクションのインテントフィルト構成でアクティビティを開始するために使用されていることがわかります。通常、暗黙の開始は、コンポーネントの特定の情報は知らないが、外部アクションは知っているコンポーネントの開始に使用されます。
2.4活動開始モード
この知識ポイントは、面接時に審査官が一般的に使用するものでもあり、実際の戦闘でより頻繁に使用するポイントでもあります。\ AndroidManifestファイルでアクティビティが定義されている場合、要素のlaunchMode属性を使用して、アクティビティをタスクに関連付ける方法を指定できます。値は次のとおりです。
- 標準(デフォルトの起動モード)
- シングルトップ
- singleTask
- singleInstance
起動モードが異なると、アクティビティの起動時に実行されるロジックも異なります。システムは、起動モードに応じてアクティビティを異なるアクティビティスタックに保存します。上記の4つのモードの詳細については、タスクとリターンスタックに関するGoogleのドキュメントを参照してください。
2.5 ActivityManagerServiceクラス図の分析
ActivityManagerServiceは、Androidによって提供されるJavaレイヤーバインダーサービスであり、システムの4つの主要コンポーネントの起動、切り替え、スケジューリング、アプリケーションプロセスの管理とスケジューリングを担当しますが、そのコードは扱いにくく、時間がかかります。事前に理解していない場合、分析は次のようになりますめまいになります。次のように、まずクラス図の実装を見てみましょう。
以下は、関連するクラス関数の簡単な紹介です。
-
ActivityManagerService
アクティビティ管理メカニズムのバインダーサーバーは、システムサービスに属しています。アクティビティのさまざまな動作の管理、アクティビティのライフサイクルの制御、メッセージイベントのディスパッチ、メモリ不足の管理などに使用されます。プロセス間通信に使用できるIBinderインターフェイスを実装しました -
ActivityManagerProxy
AMSサービスプロキシ、サードパーティアプリケーションはこのクラスを使用してAMSへのリモートRPC要求を実装します -
ActivityStarter
AMSは、非常に多くのことを処理する必要があります。したがって、ActivityStarterは、アクティビティのインテントとフラグ、および関連するスタックとタスクレコードを処理するために作成されました。 -
混乱することなく多くのアクティビティで連携するためのActivityStackの
順序、Androidプラットフォーム、アクティビティを管理するためのスタックメカニズムの設計、高度なサイクルアウトの原則への準拠、システムは常に上部に表示されます -
ActivityStackSupervisor
は、すべてのアクティビティスタックの管理を担当します。3つのアクティビティスタック、mHomeStack、mFocusedStack、およびmLastFocusedStackは内部で管理されます。その中で、mHomeStackはLauncherに関連するアクティビティスタックを管理し、mFocusedStackは現在フォアグラウンドアクティビティに表示されているアクティビティスタックを管理し、mLastFocusedStackはフォアグラウンドアクティビティに最後に表示されたアクティビティスタックを管理します。
2.6 ApplicationThreadクラス図の分析
AMSがzygoteプロセスの助けを借りてターゲットプロセスを作成した後、中間プロセスを使用してターゲットプロセスコンポーネントの制御を完了する必要があります。これがApplicationThreadの番です。AMSがターゲットプロセスの4つの主要コンポーネントの管理とスケジューリングを完了するのはこのためです。 、そのクラス図を見てみましょう:
以下は、関連するクラス関数の簡単な紹介です。
- ApplicationThread
は、それがバインダーエンティティオブジェクトであることを認識できます。これは、主にAMSとの通信とAMSからのさまざまなRPCコマンドの受信を担当し、4つの主要コンポーネントの管理と制御を完了します。ApplicationThreadProxyApplicationThreadサービスエージェント。通常、サードパーティはこれを使用してApplicationThreadを完了します。リモート呼び出し
- ActivityThreadに
は、mainの機能と同様のプロセスのメインスレッドへの入り口があります。これは、ルーパーループを確立し、AMSの4つの主要コンポーネントとライフサイクルのさまざまなスケジューリングを支援する役割を果たします。
2.7 ActivityRecord、TaskRecord、ActivityStackの概要
Activityの開始には、いくつかの非常に重要なデータ構造、つまり、ActivityRecord、TaskRecord、ActivityStack、およびProcessRecordが関係しています。これらのデータ構造間の関係は、次のクラス図の関係で表すことができます。
ここでは、上記のクラス図の概要がありますが、それらの直列接続については、とりあえずここでは示しません。次のソースコードで触れますので、簡単に個別に紹介しましょう。
- ProcessRecord
このデータ構造は、1つ以上のActivityRecordに対応するアプリプロセスに対応します(もちろん、Serviceなどの他の4つの主要コンポーネントが存在する場合があります) - ActivityRecord
、名前が示すように、このデータ構造はActiviytに対応し、Activiytの関連情報を格納します。各ActivityRecordはTaskRecordタイプのRecordRecordのメンバータスクであるActivityRecordのメンバータスクであり、レコードが属するタスクです。アクティビティとActivityRecordは1対1ではなく、1対多です。これは、Actitiyに複数の起動メソッドがあり、その結果、複数のActivityRecordsになる可能性があるためです。 - TaskRecord
TaskRecordは、1つ以上のActivityRecordsで構成されます。これは、私たちがよく言うタスクスタックであり、後入れ先出しの特性を備えています - ActivityStackは
TaskRecordを管理するために使用され、タイプRecordのメンバーmTaskHistoryを持ち、TaskRecordを格納するために使用されます - ActivityStackSupervisor
は、すべてのアクティビティスタックの管理を担当します。3つのアクティビティスタック、mHomeStack、mFocusedStack、およびmLastFocusedStackは内部で管理されます。その中で、mHomeStackはLauncherに関連するアクティビティスタックを管理し、mFocusedStackは現在フォアグラウンドアクティビティに表示されているアクティビティスタックを管理し、mLastFocusedStackはフォアグラウンドアクティビティに最後に表示されたアクティビティスタックを管理します。
さて、ここでは詳しく説明しません。みんなに基本的な概念を持たせましょう。上記のナレッジポイントに関しては、ブログActivityRecord、TaskRecord、ActivityStack、およびActivity開始モードを強くお勧めします。
概要
意外にも、Activityスタートアップの予備知識のために多くのことを書きました。みんなのために読むのと、レイアウトの美しく詳細な説明の便宜のために、最初にここに行きます。Acitivityスタートアップのソースコードレベルを本当に理解したい場合は、それを行う必要があります。うまく準備しないと、読むのがますます混乱して無力になり、読むのがとても難しくなるので、あきらめることがあります。左側に1つの知識ポイントと1つの知識ポイントがあります。私もここに来たので、なぜ私がそんなことを言ったのかと聞かないでください。私は混乱して無力で、これについて心の中で考えていました。だから男たちは精神的に準備されなければならず、途中であきらめてはいけません!次の章では、実際の戦闘分析に正式に取り掛かろうとしています。引き続き注目してください。アクティビティスタートアップの詳細な分解については、Androidの4つの主要コンポーネントのアクティビティスタートアッププロセスのソースコード実装の詳細な説明を参照してください(1)。