Android SystemServer啓動流程源碼解析

簡介

Android系統中各個進程的前後順序爲:java

  • init進程 –-> Zygote進程 –> SystemServer進程 –>應用進程

其中Zygote進程由init進程啓動,SystemServer進程和應用進程由Zygote進程啓動。android

本文依據6.0源碼,主要分析SystemServer進程的啓動流程。注意,是啓動流程,不是啓動過程。啓動過程的解析能夠移步個人另外一片博文Zygote啓動流程源碼解析SystemServer進程的做用是啓動各類核心服務,例如InstallerActivityManagerServiceWindowManagerServicePowerManagerService等等。這些服務會在開機時啓動。因爲加載的服務不少,相對很耗時,因此android系統在開機時速度很慢,可是一次加載以後,方便後續全部應用程序調用,因此這個代價仍是很是值得的。因爲加載的服務實在太多,故本文不可能分析全部的服務。分析完主要流程後,會適當舉例分析,其他服務還請自行查看。從Android Zygote啓動流程源碼解析一文中能夠看到:Zygote進程forkSystemServer進程後,經過反射調用SystemServer#main()。以此爲切入點,一步步分析。app

啓動流程概覽

源碼位置:frameworks/base/services/Java/com/android/server/SystemServer.java 
SystemServer#main()ide

/**
     * 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();
    }

    private void run() {
        ...
        // 建立主線程Looper
        Looper.prepareMainLooper();
        // 加載android_servers.so
        System.loadLibrary("android_servers");
        // 建立Context對象
        createSystemContext();
        // 建立SystemServiceManager對象
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        // 將剛建立的SystemServiceManager對象添加進LocalServices屬性sLocalServiceObjects
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        // Start services.
        try {
            // 啓動系統引導相關服務
            startBootstrapServices();
            // 啓動系統核心服務
            startCoreServices();
            // 啓動應用或系統相關的服務
            startOtherServices();
        } catch (Throwable ex) {...}
        ...
        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

上面截取了最關鍵的代碼,也是本文重點要分析的內容。能夠看到,在Main()方法中實例化以後直接調用了run()方法。在run()方法中首先獲取主線程的Looper對象,這也就意味着SystemServer後續是能夠獲取主線程中的消息。下面先分析createSystemContext()oop

建立Context對象

SystemServer#createSystemContext()this

private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
    }
  •  

createSystemContext()中首先獲取了一個ActivityThread對象,緊接着根據ActivityThread對象獲取了mSystemContextmSystemContextContext對象。這可不得了。咱們知道,ActivityThread其實就是所謂的主線程,看來ActivityThread#systemMain()這個方法大有搞頭。跟進。spa

源碼位置:frameworks/base/core/java/android/app/ActivityThread.java 
ActivityThread#systemMain().net

public static ActivityThread systemMain() {
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }
  •  

ActivityThread#systemMain()中直接new了一個ActivityThread對象,而後調用ActivityThread#attach()方法。跟進。線程

ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
           ...
        } else {
            ...
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
           ...
        }
       ...
  •  

能夠看到,調用ContextImpl的靜態方法createAppContext()獲取一個ContextImpl對象,而後調用LoadedApk(mPackageInfo是LoadedApk的一個對象)#makeApplication()建立了Application,最後調用Application#onCreate()方法。SystemServer也是一個Android進程,由此能夠看出,進程建立後最早被調用的是ActivityThread#attach(),其次纔是Application#onCreate()code

建立SystemServiceManager

回到SystemServer#run()

private void run() {
        ...
         createSystemContext();
        // 建立SystemServiceManager對象
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        // 將剛建立的SystemServiceManager對象添加進LocalServices屬性sLocalServiceObjects
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...
    }
  •  

獲取到Context對象後,建立mSystemServiceManager用於管理各類系統服務。接下來就開始啓動各類系統服務。文章有限,這裏以啓動InstallerActivityManagerServiceWindowManagerService爲例進行分析,其他還請自行查看。

啓動各類服務

ActivityThread#startBootstrapServices()

startBootstrapServices();
  startCoreServices();
  startOtherServices();
  •  

啓動Installer

private void startBootstrapServices() {
        Installer installer = mSystemServiceManager.startService(Installer.class);
    }
  •  

經過SystemServiceManager#startService()方法,就啓動了Installer。跟進。

源碼位置:frameworks/base/services/core/java/com/android/server/SystemServerManager.java 
SystemServiceManager#startService()

public <T extends SystemService> T startService(Class<T> serviceClass) {
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        Constructor<T> constructor = serviceClass.getConstructor(Context.class);
        service = constructor.newInstance(mContext);
        mServices.add(service);
        service.onStart();
        return service;
    }
  •  

傳入的泛型必須是抽象類SystemService的子類,而且經過反射獲得實例。最後添加進ArrayList<SystemService> mServices中以便管理。最後調用泛型Service中抽象父類的抽象方法onStart()的具體實現。跟進。

源碼位置:frameworks/base/services/core/java/com/android/server/pm/Installer.java 
Installer#onStart()

public void onStart() {
        mInstaller.waitForConnection();
    }
  •  

mInstallerInstallerConnection對象。跟進。

源碼位置:frameworks/base/services/core/java/com/android/internal/os/InstallerConnection.java 
InstallerConnection#waitForConnection()

public void waitForConnection() {
        for (;;) {
            if (execute("ping") >= 0) {
                return;
            }
            Slog.w(TAG, "installd not ready");
            SystemClock.sleep(1000);
        }
    }
  •  

這裏有個死循環,說明只有execute()方法執行成功而且返回值大於0以後纔會繼續啓動其餘服務。不然一直卡在這裏。跟進。

public int execute(String cmd) {
        String res = transact(cmd);
        try {
            return Integer.parseInt(res);
        } catch (NumberFormatException ex) {
            return -1;
        }
    }

    public synchronized String transact(String cmd) {
        if (!connect()) {
            return "-1";
        }

        if (!writeCommand(cmd)) {
            if (!connect() || !writeCommand(cmd)) {
                return "-1";
            }
        }
        final int replyLength = readReply();
        if (replyLength > 0) {
            String s = new String(buf, 0, replyLength);
            return s;
        } else {
            return "-1";
        }
    }

    private boolean connect() {
        if (mSocket != null) {
            return true;
        }
        Slog.i(TAG, "connecting...");
        try {
            mSocket = new LocalSocket();

            LocalSocketAddress address = new LocalSocketAddress("installd",
                    LocalSocketAddress.Namespace.RESERVED);

            mSocket.connect(address);

            mIn = mSocket.getInputStream();
            mOut = mSocket.getOutputStream();
        } catch (IOException ex) {
            disconnect();
            return false;
        }
        return true;
    }

    private boolean writeCommand(String cmdString) {
        final byte[] cmd = cmdString.getBytes();
        final int len = cmd.length;
        if ((len < 1) || (len > buf.length)) {
            return false;
        }

        buf[0] = (byte) (len & 0xff);
        buf[1] = (byte) ((len >> 8) & 0xff);
        try {
            mOut.write(buf, 0, 2);
            mOut.write(cmd, 0, len);
        } catch (IOException ex) {
            Slog.e(TAG, "write error");
            disconnect();
            return false;
        }
        return true;
    }
  •  

爲了方便查看,連續貼了三個相關的方法。稍微顯得有些長,不要緊,咱們一個個去分析。首先調用connect()方法經過Socket鏈接installd服務端。接着調用writeCommand()方法寫入要發送的數據,這裏參數cmdStringping,因此len=4。最後經過readReply()方法,讀取服務端返回的數據,轉換成String形式返回。以後啓動其它服務。

啓動ActivityManagerService

private void startBootstrapServices() {
        mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
    }
  •  

這裏和啓動Installer不一樣,startService()傳入的是ActivityManagerService.Lifecycle.class,以後調用startService()返回值的getService()方法。跟進。

源碼位置:frameworks/base/services/core/java/com/android/servicer/am/ActivityManagerService.java 
ActivityManagerService$Lifecycle

public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }
  •  

LifecycleActivityManagerService的一個final類型的靜態內部類。在分析SystemServiceManager#startService()說道:經過反射獲得實例。最後添加進ArrayList<SystemService> mServices中以便管理。最後調用泛型Service中抽象父類的抽象方法onStart()的具體實現。因此這裏首先會實例化ActivityManagerService對象,而後調用Lifecycle#onStart()。在Lifecycle#onStart()中調用ActivityManagerService#start()。最後getService()返回實例化過的ActivityManagerService對象。因爲ActivityManagerService#start()相關代碼太多,這裏就不詳細展開了。有時間單獨寫一篇博文解析。

啓動WindowManagerService

private void startOtherServices() {
          wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore);
    }
  •  

這裏和啓動InstallerActivityManagerService又有些不一樣,直接調用WindowManagerService#main()。真的是簡單粗暴。跟進。

public static WindowManagerService main(final Context context,
            final InputManagerService im,
            final boolean haveInputMethods, final boolean showBootMsgs,
            final boolean onlyCore) {
        final WindowManagerService[] holder = new WindowManagerService[1];
        DisplayThread.getHandler().runWithScissors(new Runnable() {
            @Override
            public void run() {
                holder[0] = new WindowManagerService(context, im,
                        haveInputMethods, showBootMsgs, onlyCore);
            }
        }, 0);
        return holder[0];
    }

 

相關代碼太長,有時間單獨再寫一篇。其它服務的啓動和上面三種服務啓動截然不同,感興趣的同窗請自行查看。2點多,有些困。明天還要上班,古耐

相關文章
相關標籤/搜索