按計劃本來從這章開始寫四大元件的啟動過程的,但是看看原始碼結構發現為了說的更明白還是先寫一點系統framework層啟動的內容,幫助理解四大元件的啟動以及管理過程。我們知道四大元件管理是通過一些服務以及執行緒實現的,所以先把一些基本概念弄清楚比較好,比如AMS(ActivityManagerService)、PMS(PackageManagerService)等系統服務的作用以及呼叫方式,瞭解這些之後再看四大元件相對容易些,因此我們本章先介紹系統啟動、部分系統服務的作用。
Zygote啟動過程
Zygote是一個孕育器,Android系統所有的應用程式以及系統服務SystemServer都是有Zygote程式孕育(fork)而生的,因此Zygote在Android啟動過程中起著決定作用。Zygote的啟動是從它的main函式開始的,因此我們從這個函式開始分析。整個過程看下面的時序圖。
下面我們開始根據時序圖進行分析。
Step 0.ZygoteInit.main
public static void main(String argv[]) {
...
try {
...
registerZygoteSocket(socketName);
...
preload();
...
gcAndFinalize();
...
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
...
} catch (Throwable ex) {
...
}
}複製程式碼
首先呼叫registerZygoteSocket方法,建立一個socket介面,用來和ActivityManagerService通訊,然後呼叫preload方法預載入一些資源等;然後呼叫gcAndFinalize方法釋放一些記憶體;然後呼叫startSystemServer方法啟動SystemServer元件,然後呼叫runSelectLoop方法,建立一個無限迴圈,在socket介面上等待ActivityManagerService請求建立新的應用程式程式;最後呼叫closeServerSocket方法關閉上面建立的socket。
Step 1.ZygoteInit.registerZygoteSocket
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
...
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}複製程式碼
這個sServerSocket是通過傳入FileDescriptor(檔案描述者)通過new一個來LocalServerSocket建立的。
Step 2.LocalServerSocket
public LocalServerSocket(FileDescriptor fd) throws IOException
{
impl = new LocalSocketImpl(fd);
impl.listen(LISTEN_BACKLOG);
localAddress = impl.getSockAddress();
}複製程式碼
在LocalServerSocket建構函式中又new了一個LocalSocketImpl,然後呼叫LocalSocketImpl的listen方法,最後通過getSockAddress方法獲取LocalSocketAddress物件。
Step 3.LocalSocketImpl
/*package*/ LocalSocketImpl(FileDescriptor fd) throws IOException
{
this.fd = fd;
}複製程式碼
這裡只是傳入了FileDescriptor(檔案描述者)。
Step 5.ZygoteInit.preload
static void preload() {
...
beginIcuCachePinning();
...
preloadClasses();
...
preloadResources();
...
preloadOpenGL();
...
preloadSharedLibraries();
preloadTextResources();
...
}複製程式碼
這裡主要是預載入,1.預載入ICU快取,2.執行Zygote程式初始化,預載入一些普通類,3.預載入mResources,4.預載入OpenGL,5.預載入共享庫,6.預載入TextView的字型快取。
Step 12.ZygoteInit.gcAndFinalize
/*package*/ static void gcAndFinalize() {
final VMRuntime runtime = VMRuntime.getRuntime();
...
System.gc();
runtime.runFinalizationSync();
System.gc();
}複製程式碼
這裡主要是呼叫System.gc來釋放一部分記憶體。
Step 13.ZygoteInit.startSystemServer
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
...
int pid;
try {
...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
...
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}複製程式碼
首先Zygote會通過呼叫Zygote.forkSystemServer方法來建立一個新的程式來啟動SystemServer,並且返回這個程式的pid,如果pid為0,並且有另外一個Zygote則會執行waitForSecondaryZygote關閉另外的Zygote程式,然後呼叫handleSystemServerProcess方法。
Step 16.ZygoteInit.handleSystemServerProcess
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
...
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.invokeWith != null) {
...
} else {
...
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}複製程式碼
首先呼叫closeServerSocket方法關閉socket,然後呼叫performSystemServerDexOpt來建立安裝連線InstallerConnection,最後呼叫RuntimeInit.zygoteInit方法。
Step 19.RuntimeInit.zygoteInit
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
...
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}複製程式碼
首先呼叫nativeZygoteInit函式來執行一個Binder程式間通訊機制初始化工作,然後就可以在程式間進行通訊了,然後執行applicationInit方法。
Step 21.RuntimeInit.applicationInit
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}複製程式碼
這裡主要是執行一個invokeStaticMain方法來呼叫SystemServer的main方法。
Step 24.ZygoteInit.runSelectLoop
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
...
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
...
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}複製程式碼
這裡通過acceptCommandPeer來建立ActivityManagerService與Socket的連線,然後呼叫ZygoteConnection.runOnce方法來建立新的應用程式。
SystemServer啟動過程
我們從上面的Step 13 知道了SystemServer的main函式呼叫位置,下面我們分析一下SystemServer的啟動過程。
在main方法中new了一個SystemServer然後呼叫它的run方法:
private void run() {
try {
...
// Mmmmmm... more memory!
// 清除vm記憶體增長上限,由於啟動過程需要較多的虛擬機器記憶體空間
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
// 設定記憶體的可能有效使用率為0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
// 訪問環境變數前,需要明確地指定使用者
Environment.setUserRequired(true);
// Within the system server, any incoming Bundles should be defused
// to avoid throwing BadParcelableException.
BaseBundle.setShouldDefuse(true);
// Ensure binder calls into the system always run at foreground priority.
// 確保當前系統程式的binder呼叫,總是執行在前臺優先順序(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
// Increase the number of binder threads in system_server
BinderInternal.setMaxThreads(sMaxBinderThreads);
...
// 準備主執行緒的Looper
Looper.prepareMainLooper();
// Initialize native services.
// 載入android_servers.so庫,該庫包含的原始碼在frameworks/base/services/目錄下
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
// 初始化系統上下文
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//將mSystemServiceManager新增到本地服務的成員sLocalServiceObjects
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
...
}
// Start services.
try {
...
startBootstrapServices(); // 啟動引導服務
startCoreServices(); // 啟動核心服務
startOtherServices(); // 啟動其他服務
} catch (Throwable ex) {
...
} finally {
...
}
...
// Loop(迴圈) forever.
Looper.loop();
...
}複製程式碼
Step 3.Build.ensureFingerprintProperty
public static void ensureFingerprintProperty() {
if (TextUtils.isEmpty(SystemProperties.get("ro.build.fingerprint"))) {
try {
SystemProperties.set("ro.build.fingerprint", FINGERPRINT);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Failed to set fingerprint property", e);
}
}
}複製程式碼
確認裝置的指紋屬性。
Step 7.Looper.prepareMainLooper()
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}複製程式碼
準備main looper,這個詳細的過程我們下一章再講,這裡先看一下流程。
Step 10.SystemServer.performPendingShutdown
private void performPendingShutdown() {
final String shutdownAction = SystemProperties.get(
ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
if (shutdownAction != null && shutdownAction.length() > 0) {
// 是否重啟
boolean reboot = (shutdownAction.charAt(0) == '1');
final String reason;
if (shutdownAction.length() > 1) {
reason = shutdownAction.substring(1, shutdownAction.length());
} else {
reason = null;
}
if (PowerManager.REBOOT_RECOVERY_UPDATE.equals(reason)) {
File packageFile = new File(UNCRYPT_PACKAGE_FILE);
if (packageFile.exists()) {
String filename = null;
try {
filename = FileUtils.readTextFile(packageFile, 0, null);
} catch (IOException e) {
Slog.e(TAG, "Error reading uncrypt package file", e);
}
if (filename != null && filename.startsWith("/data")) {
if (!new File(BLOCK_MAP_FILE).exists()) {
...
return;
}
}
}
}
ShutdownThread.rebootOrShutdown(null, reboot, reason);
}
}複製程式碼
這裡主要是通過關機的action來判斷是否重啟或者關機。
Step 13.SystemServer.createSystemContext
private void createSystemContext() {
// 初始化ActivityThread,並設定預設主題
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}複製程式碼
首先呼叫ActivityThread.systemMain方法建立ActivityThread物件然後獲取mSystemContext,並且設定預設系統主題。
Step 15.ActivityThread.systemMain
public static ActivityThread systemMain() {
...
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}複製程式碼
建立ActivityThread物件,並呼叫attach方法。
Step 17.ResourcesManager.getInstance
public static ResourcesManager getInstance() {
synchronized (ResourcesManager.class) {
if (sResourcesManager == null) {
sResourcesManager = new ResourcesManager();
}
return sResourcesManager;
}複製程式碼
單例模式建立ResourcesManager物件並且返回。
Step 19.ActivityThread.attach
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
} else {
...
try {
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
...
}
}
...
}複製程式碼
因為引數傳入的是true,表明是系統的執行緒,所以執行else裡面的內容,首先建立Instrumentation,然後呼叫ContextImpl.createAppContext方法建立ContextImpl,然後通過呼叫LoadedApk.makeApplication方法建立Application,然後呼叫Application.onCreate方法。
Step 22.ContextImpl.createAppContext
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
return new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
}複製程式碼
通過new ContextImpl來建立ContextImpl物件。
Step 22.LoadedApk.makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;
...
try {
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
...
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
...
return app;
}複製程式碼
通過ContextImpl.createAppContext方法建立ContextImpl物件,然後呼叫mActivityThread.mInstrumentation.newApplication方法建立Application物件,然後呼叫instrumentation.callApplicationOnCreate方法。
Step 23.ContextImpl.createAppContext
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
return new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
}複製程式碼
建立ContextImpl物件並返回。
Step 26.Instrumentation.createAppContext
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}複製程式碼
這裡主要是呼叫newApplication方法返回Application。
Step 28.Instrumentation.newApplication
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}複製程式碼
呼叫class.newInstance方法建立Application,然後呼叫Application.attach方法,向Application中傳入context。
Step 32.Application.attach
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}複製程式碼
通過ContextImpl.getImpl方法獲取LoadedApk物件。
Step 34.Instrumentation.callApplicationOnCreate
public void callApplicationOnCreate(Application app) {
app.onCreate();
}複製程式碼
這裡開始呼叫Application的onCreate方法。
Step 39.ActivityThread.getSystemContext
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}複製程式碼
通過ContextImpl.createSystemContext建立mSystemContext。
Step 40.ContextImpl.createSystemContext
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}複製程式碼
建立ContextImpl並且返回。
Step 43.SystemServer.startBootstrapServices
private void startBootstrapServices() {
...
// 安裝服務
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity管理服務
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
// 電量管理服務
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
...
// 管理LEDs和背光燈服務
mSystemServiceManager.startService(LightsService.class);
// 顯示管理服務
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// 包管理服務
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
...
// 啟動使用者管理服務
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
//初始化安裝包資源的屬性快取
AttributeCache.init(mSystemContext);
// 啟動系統程式的應用例項
mActivityManagerService.setSystemProcess();
// 啟動感測器服務
startSensorService();
}複製程式碼
這裡主要是啟動系統引導服務。
Step 44.SystemServer.startCoreServices
private void startCoreServices() {
// 啟動電池服務
mSystemServiceManager.startService(BatteryService.class);
// 啟動應用統計服務
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// 啟動WebView更新服務
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}複製程式碼
啟動核心服務。
Step 45.SystemServer.startOtherServices
這裡程式碼就不貼了,都是啟動服務的程式碼,這裡有很多服務,我簡單列一下服務並說一下服務基本功能。
服務 | 名稱 | 服務 | 名稱 |
---|---|---|---|
SchedulingPolicyService | CameraService | ||
TelecomLoaderService | AccountManagerService.Lifecycle | ||
ContentService.Lifecycle | VibratorService | ||
ConsumerIrService | AlarmManagerService | ||
InputManagerService | WindowManagerService | ||
VrManagerService | PersistentDataBlockService | ||
MetricsLoggerService | IpConnectivityMetrics | ||
PinnerService | InputMethodManagerService.Lifecycle | ||
MountService.Lifecycle | UiModeManagerService | ||
LockSettingsService.Lifecycle | BluetoothService | ||
DeviceIdleController | NsdService | ||
StatusBarManagerService | ClipboardService | ||
NetworkManagementService | WifiService | ||
NetworkScoreService | NetworkStatsService | ||
NetworkPolicyManagerService | WifiNanService | ||
WifiP2pService | TextServicesManagerService.Lifecycle | ||
WifiScanningService | ConnectivityService | ||
RttService | DevicePolicyManagerService.Lifecycle | ||
UpdateLockService | RecoverySystemService | ||
NotificationManagerService | DeviceStorageMonitorService | ||
LocationManagerService | CountryDetectorService | ||
SearchManagerService.Lifecycle | DropBoxManagerService | ||
AudioService.Lifecycle | DockObserver | ||
ThermalObserver | MidiService.Lifecycle | ||
UsbService.Lifecycle | SerialService | ||
HardwarePropertiesManagerService | NightDisplayService | ||
JobSchedulerService | SoundTriggerService | ||
BackupManagerService.Lifecycle | AppWidgetService | ||
VoiceInteractionManagerService | GestureLauncherService | ||
SensorNotificationService | ContextHubSystemService | ||
DiskStatsService | SamplingProfilerService | ||
NetworkTimeUpdateService | CommonTimeManagementService | ||
EmergencyAffordanceService | DreamManagerService | ||
AssetAtlasService | GraphicsStatsService | ||
PrintManagerService | RestrictionsManagerService | ||
MediaSessionService | HdmiControlService | ||
TvInputManagerService | MediaResourceMonitorService | ||
TvRemoteService | MediaRouterService | ||
TrustManagerService | FingerprintService | ||
ShortcutService.Lifecycle | LauncherAppsService | ||
MediaProjectionManagerService | WearBluetoothService | ||
WearWifiMediatorService | WearTimeService | ||
MmsServiceBroker | RetailDemoModeService | ||
NsdService | WallpaperManagerService.Lifecycle |
參考:
Android系統啟動-SystemServer下篇
Android系統程式Zygote啟動過程的原始碼分析
注
原文地址:Android系統原始碼分析--Zygote和SystemServer啟動過程
Android開發群:192508518
微信公眾賬號:Code-MX
注:本文原創,轉載請註明出處,多謝。