序文
私は長年Android開発者として多くのアプリケーションを作成してきましたが、アプリはどのように起動するのでしょうか。デスクトップがクリックで始まると言うなら、そうです。しかし、その起動プロセスはどうですか?そのような質問で、段階的に学びましょう。
Androidの起動プロセス
通常、どのプラットフォームでも、次のコンポーネントが段階的にロードおよび実行されます。
- ブートローダー
- Uブート(オプション)
- カーネル
- アンドロイド
Androidプロセスの順序は次のとおりです。
- 初期化
- 受精卵
- システムサーバー
- サービスマネージャ
- その他のデーモンとプロセス
- アプリケーション
具体的な状況は次のとおりであり、これら2つの写真を組み合わせるのは興味深いことです。
-
ブートROM:電源を入れると、ブートチップコードが事前定義された場所(ROMに統合)から実行を開始し、ブートプログラムBootLoaderをRAMにロードしてから実行します。(このステップは、「チップメーカー」によって設計および実装されています)
-
ブートローダー:ブートローダーは実行を開始します。まず、ハードウェアの初期化を完了し、オペレーティングシステムを起動して起動します。(このステップは、「機器メーカー」によって設計および実装されています)
-
カーネル:LinuxカーネルはAndroidのコアであり、プロセスの作成、プロセス間通信、デバイスドライバー、ファイルシステム管理などを担当します。Androidは、メインストリームカーネルにカスタムパッチを適用して、ウェイクロックなど、Androidの実行に必要な特定の機能をサポートします。カーネルは、非圧縮または圧縮イメージとしてロードできます。ロード時に、ルートファイルシステム(通常はカーネルコマンドライン引数として渡されます)をマウントし、ユーザースペースで最初のアプリケーションを起動します。(このステップは、Androidカーネル開発プロセスに関与する必要があるものです)
-
Android:Androidシステムと主要なLinuxディストリビューション、ブートプロセスのLinuxカーネル部分は類似しています。これらの最大の違いは、initプログラムの違いです。これは、initプログラムが起動プロセス中にシステムを決定するため、どのデーモンが発生するかを示します。とサービスが開始され、どのようなUIが表示されます。
したがって、initプログラムは、Androidの起動プロセスを分析する上で最もコアなプログラムです。
-
initおよびinit.rc :カーネルの起動時に実行される最初のユーザースペースアプリケーションは、ルートフォルダーにあるinit実行可能ファイルです。このプロセスは、「init.rc」スクリプトと呼ばれる起動スクリプトを解析します。これは、Androidが正しく機能するために必要なすべてのプロセス、デーモン、およびサービスを開始するためにAndroid用に設計された言語で書かれています。これは、early-init、on-boot、on-post-fsなどのさまざまなタイプの実行時間を提供します。(ユーザースペースの創始者)
-
デーモンとサービス:initプロセスは、rild、vold、mediaserver、adbなどのさまざまなデーモンとプロセスを作成します。各プロセスは独自の機能を担当します。これらのプロセスの説明は、この記事の範囲を超えています。代わりに、「Zygote」プロセスについて詳しく説明します。
-
Service Manager:Service Managerプロセスは、システムで実行されているすべてのサービスを管理します。作成されたすべてのサービスはこのプロセスに登録され、この情報は他のプロセス/アプリケーションが将来参照できるようになります。
-
Zygote:Zygoteは、起動時に作成される最初のinitプロセスの1つです。「接合子」という用語は、生物学的な「子孫を生み出すための最初の細胞分裂の形成」に基づいています。同様に、「zygote in android」は、Dalivik VM(ART)とフォークを初期化して、各androidプロセスをサポートする複数のインスタンスを作成します。VMインスタンス間の共有コードの使用を容易にし、メモリフットプリントとロード時間を削減し、組み込みシステムに最適です。Zygoteは、サーバーソケットにリスナーをインストールするだけでなく、後でAndroidアプリケーションで使用できるようにクラスとリソースをプリロードします。完了すると、システムサーバーが起動します。
-
System Server:SystemServerプロセスは、Androidで利用可能なすべてのサービスを開始します。
この記事では、初期化からアプリケーションの起動までに焦点を当てます。
1. Zygoteとは何ですか?
Androidシステムでは、zygoteはプロセスの名前です。AndroidはLinuxシステムに基づいています。電話の電源を入れると、Linuxカーネルがロードされた後に「init」と呼ばれるプロセスが開始されます。Linuxシステムでは、すべてのプロセスがinitプロセスによってフォークされ、 zygoteプロセスも例外ではありません。
Zygoteは、仮想マシンプロセスであり、仮想マシンインスタンスのインキュベーターです。システムがAndroidアプリケーションの実行を要求するたびに、Zygoteは子プロセスをフォーク(分割)してアプリケーションを実行します。
1.1 app_main.cpp
フレームワーク/base/cmds/app_process/app_main.cpp
app_main.cppは、Zygoteの起動後に実行されます。C / c ++ / javaであるかどうかに関係なく、それらのエントリはmain()です。これは、Activityが表示されている場合と同様に、onCreate()メソッドを直接検索します。
1.1.1 main()
int main(int argc, char* const argv[])
{
...
//注释1:初始化AppRuntime(AndroidRunTime)
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
//注释2:设置zygote模式
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
}
...
}
Vector<String8> args;
if (!className.isEmpty()) {
...
} else {
// 我们处于 zygote 模式。
maybeCreateDalvikCache();
// 注释3:在 zygote 模式下,将参数传递给 ZygoteInit.main() 方法。
if (startSystemServer) {
args.add(String8("start-system-server"));
}
//PROP_VALUE_MAX = 92;
char prop[PROP_VALUE_MAX];
...
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (zygote) {
//注释4:调用 AndroidRuntime.start() 方法
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
...
} else {
...
}
}
注1:実際にはAndroidRuntime(ART)であるAppRuntimeを初期化します。
注2:接合子モードを設定します。
注3:パラメーターをZygoteInit.main()メソッドに渡します。
注4:ZygoteInitを起動します。ここでのZygoteInitは、zygoteプロセスのスタートアップクラスです。これについては以下で説明します。まず、AndroidRuntimeのstart()メソッドを見てみましょう。
1.2 AndroidRuntime.cpp
フレームワーク/base/core/jni/AndroidRuntime.cpp
Android仮想マシン
1.2.1 start()
/*
* Start the Android runtime. This involves starting the virtual machine and calling the "static void main(String[] args)" method in the class named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//注释1:启动虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
//注释2:注册安卓功能(JNI)
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
...
/*
* 启动虚拟机。 该线程成为VM的主线程,直到VM退出才会返回。
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
...
} else {
...
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
...
} else {
//注释3
env->CallStaticVoidMethod(startClass, startMeth, strArray);
if (env->ExceptionCheck())
threadExitUncaughtException(env);
}
}
...
}
复制代码
注1:VM(仮想マシン)を起動します
注2:Android関数の登録(JNI)
注3:JNIを使用して、Zygotelnitのmain()メソッドを呼び出します。ここでのZygotelnitはクラスファイルです。つまり、ここからjavaフィールドに入ります。
JNI:ネイティブ(C / C ++)レイヤーとJavaレイヤーを接続するブリッジ。
1.3 ZygoteInit.java
フレームワーク/base/core/java/com/android/internal/os/ZygoteInit.java
/**
* zygote 进程的启动类。
*/
public class ZygoteInit {
...
}
复制代码
これは、Zygoteプロセスのエントリポイントです。Zygoteサービスを作成し、リソースをロードし、アプリケーションへのフォークの準備プロセスに関連するその他のタスクを処理します。
1.3.1 main()
@UnsupportedAppUsage
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
try {
...
boolean startSystemServer = false;
//argv:用于指定 Zygote 配置的命令行参数。
...
if (!enableLazyPreload) {
//注释1:预加载资源。
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}
...
//注释2:创建Zygote 的 LocalServerSocket 。
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//注释3:开始fork我们的SystemServer进程。
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
...
}
...
// 注释4:zygote 永久循环。
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
...
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
...
}
复制代码
注1:リソースをプリロードします。
注2:ZygoteのLocalServerSocketを作成します。
注3:SystemServerプロセスのフォークを開始します。
注4:接合子は永久にループします。
ここでは、forkSystemServer();を見ていきます。
1.3.2 forkSystemServer()
/**
* Prepare the arguments and forks for the system server process.
*
* @return A {@code Runnable} that provides an entrypoint into system_server code in the child
* process; {@code null} in the parent.
*/
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
//命令行来启动SystemServer
//ZygoteInit.main(String argv[])里面的argv 跟这个类似
String[] args = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
//处理与 zygote spawner 相关的 args 的参数解析。
ZygoteArguments parsedArgs;
int pid;
try {
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
parsedArgs = ZygoteArguments.getInstance(commandBuffer);
} catch (EOFException e) {
throw new AssertionError("Unexpected argument error for forking system server", e);
}
commandBuffer.close();
...
//请求 fork 系统服务器进程
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
复制代码
ここでシステムサーバーが起動します。以下で彼を見てみましょう。
2、SystemServer
システムサーバーはSystemServerでもあります。SystemServerは、ActivityTaskManagerService、ActivityManagerService、PackageManagerService、WindowManagerServiceなどの92のサービスを含むプロセスでもあります。
Androidフレームワークには2つの非常に重要なプロセスがあります。
-
SystemServerプロセス。
-
Zygoteプロセス。
2.1 SystemServer.java
フレームワーク/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
...
}
复制代码
2.1.1 main()
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
...
}
复制代码
run()で何が使われているのか見てみましょう。
2.1.2 run()
private void run() {
try {
...
// 注释1:加载动态库libandroid_service.so。
System.loadLibrary("android_servers");
// 注释2:创建系统上下文。
createSystemContext();
// 调用每个进程的主线模块初始化。
ActivityThread.initializeMainlineModules();
// 注释3:创建 SystemServiceManager。
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// 为可并行化的 init 任务准备线程池
SystemServerInitThreadPool.start();
...
} finally {
}
// 注释4:Start services。
try {
//下面咱们看看这个三个方法启动什么服务
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
...
} finally {
t.traceEnd(); // StartServices
}
...
// 注释5:Loop 永久循环。
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
复制代码
注1:ダイナミックライブラリlibandroid_service.soをロードします。
注2:システムコンテキストを作成します。
注3:SystemServiceManagerを作成します。
注4:サービスの開始(startBootstrapServices、startCoreServices、startOtherServices)
注5:ループは永久にループします。
2.1.3 createSystemContext()
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
复制代码
システムコンテキストオブジェクトmSystemContextを初期化し、デフォルトのテーマを設定します。mSystemContextは、実際にはContext(ContextImpl)オブジェクトです。
ActivityThread.systemMain()が呼び出されると、ActivityThread.attach(true)が呼び出され、attach()で、Applicationオブジェクトが作成され、Application.onCreate()が呼び出されます。
2.1.4 startBootstrapServices()
/**
* 启动系统引导服务,因为这些服务之间有复杂的相互依赖关系,所以都放在了这个方法里面。
*/
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
...
final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
// PlatformCompat Service 由 ActivityManagerService, PackageManagerService 和 其他服务做使用
PlatformCompat platformCompat = new PlatformCompat(mSystemContext);
ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
new PlatformCompatNative(platformCompat));
AppCompatCallbacks.install(new long[0]);
mSystemServiceManager.startService(FileIntegrityService.class);
Installer installer = mSystemServiceManager.startService(Installer.class);
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
startMemtrackProxyService();
// StartActivityManager
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
//初始化 ActivityManagerService
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
mDataLoaderManagerService = mSystemServiceManager.startService(
DataLoaderManagerService.class);
mIncrementalServiceHandle = startIncrementalService();
t.traceEnd();
//初始化PowerManagerService(电源服务),需要提前启动,因为其他服务需要它。
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
mSystemServiceManager.startService(ThermalManagerService.class);
// 电源管理已经开启,ActivityManagerService负责电源管理功能
mActivityManagerService.initPowerManagement();
mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
...
mSystemServiceManager.startService(LightsService.class);
// Package manager isn't started yet; need to use SysProp not hardware feature
if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
}
// 初始化DisplayManagerService(显示管理器)
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// Start the package manager.
try {
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
}
// 现在PackageManagerService已经启动,注册 dex 加载报告器来捕获系统服务加载的任何 dex 文件。
// 这些 dex 文件将由 BackgroundDexOptService 优化。
SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...
//将AMS等添加到ServiceManager中
mActivityManagerService.setSystemProcess();
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
try {
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
} finally {
}
}
}
...
mSensorServiceStart = SystemServerInitThreadPool.submit(() -> {
TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
startSensorService();
}, START_SENSOR_SERVICE);
// startBootstrapServices
}
复制代码
主な変更点:
-
ActivityTaskManagerService(ATMS):ライフサイクルや状態の切り替えなど、アクティビティとプロセスの管理を担当します。
-
ActivityManagerService(AMS):AMNのサブクラスであり、ライフサイクルや状態の切り替えなど、3つの主要なコンポーネント(アクティビティを除く)とプロセスの管理を担当します。AMSは、ウィンドウを含むUIと対話する必要があるため、非常に複雑です。
ActivityTaskManagerService:ActivityManagerServiceからアクティビティ関連のコンテンツを取り除くことによって生成されます。
PowerManagerService(PMS):電源管理サービス。
PackageManagerService(PKMS):PMSとは呼ばれないパッケージ管理サービスは、電力管理サービスと区別するためのものです。
2.1.5 startCoreServices()
/**
* 启动核心服务。
*/
private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
// Service for system config
mSystemServiceManager.startService(SystemConfigService.class);
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
...
mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS);
mSystemServiceManager.startService(NativeTombstoneManagerService.class);
mSystemServiceManager.startService(BugreportManagerService.class);
mSystemServiceManager.startService(GpuService.class);
// startCoreServices
}
复制代码
2.1.6 startOtherServices()
/**
* 启动其他服务。
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
final Context context = mSystemContext;
VibratorService vibrator = null;
DynamicSystemService dynamicSystem = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
VpnManagerService vpnManager = null;
VcnManagementService vcnManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
NsdService serviceDiscovery = null;
WindowManagerService wm = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
InputManagerService inputManager = null;
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
MmsServiceBroker mmsService = null;
HardwarePropertiesManagerService hardwarePropertiesService = null;
PacProxyService pacProxyService = null;
...
// 现在便可以开始启动三方APP应用(如Launcher启动桌面)
mActivityManagerService.systemReady(() -> {
...
}, t);
// startOtherServices
}
复制代码
上記の手順の後、createSystemContext()を呼び出してシステムコンテキストを作成すると、mSystemContextとActivityThreadの作成が完了します。
ATMS、AMS、WMS、PKMSなどのオブジェクトが作成され、メンバー変数が初期化されています。
注:これは、システムプロセスが開始されたときのプロセスです。その後、システムが開始されます。
Launcherプログラムは、システムインターフェイスのロードと表示を完了します。
Androidのフレームワーク設計では、サーバー側とは、ここで説明したATMS、AMS、WMS、PKMSなどのすべてのアプリで共有されるシステムサービスを指します。これらの基本的なシステムサービスは、すべてのアプリで共有されます。
3.ランチャーとは
Androidシステムでは、アプリケーションはランチャーによって起動されます。実際、ランチャー自体もアプリケーションです。他のアプリケーションをインストールすると、対応するアイコンがランチャーインターフェイスに表示されます。このアイコンをクリックすると、ランチャーは対応するアプリケーションが起動します。
もちろん、他のアプリケーションでアプリケーションを起動することもできます。しかし、本質的にはstartActivity()を呼び出します。
3.1 LauncherActivity.java
フレームワーク/base/core/java/android/app/LauncherActivity.java
/**
* Displays a list of all activities which can be performed
* for a given intent. Launches when clicked.
*
* @deprecated Applications can implement this UI themselves using
* {@link androidx.recyclerview.widget.RecyclerView} and
* {@link android.content.pm.PackageManager#queryIntentActivities(Intent, int)}
*/
@Deprecated
public abstract class LauncherActivity extends ListActivity {
...
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = intentForPosition(position);
startActivity(intent);
}
}
复制代码
まとめ
全体像を添付
startActivity()について知っている場合は、直接確認できます。この投稿にはコンテンツがたくさんあるので、見ているだけでイライラします。まだご覧になっていない場合は、手を振ってください。詳細については、次の記事で説明します:❤️AndroidstartActivityソースコード分析❤️。