天天看點

Android Framework高頻面試題總結2.Activity 啟動流程,App 啟動流程

1.AMS 、PMS

1.AMS概述

AMS是系統的引導服務,應用程序的啟動、切換和排程、四大元件的啟動和管理都需要AMS的支援。從這裡可以看出AMS的功能會十分的繁多,當然它并不是一個類承擔這個重責,它有一些關聯類,這在文章後面會講到。AMS的涉及的知識點非常多,這篇文章主要會講解AMS的以下幾個知識點:

AMS的啟動流程。

AMS與程序啟動。

AMS家族。

2.AMS的啟動流程

AMS的啟動是在SyetemServer程序中啟動的,在Android系統啟動流程(三)解析SyetemServer程序啟動過程這篇文章中提及過,這裡從SyetemServer的main方法開始講起:

frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {

       new SystemServer().run();

   }

main方法中隻調用了SystemServer的run方法,如下所示。

frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
       ...
           System.loadLibrary("android_servers");//1
       ...
           mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
           LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
       ...    
        try {
           Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
           startBootstrapServices();//3
           startCoreServices();//4
           startOtherServices();//5
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
       }
       ...
   }
           

在注釋1處加載了動态庫libandroid_servers.so。

接下來在注釋2處建立SystemServiceManager,它會對系統的服務進行建立、啟動和生命周期管理。在注釋3中的startBootstrapServices方法中用SystemServiceManager啟動了ActivityManagerService、PowerManagerService、PackageManagerService等服務。

在注釋4處的startCoreServices方法中則啟動了BatteryService、UsageStatsService和WebViewUpdateService。注釋5處的startOtherServices方法中啟動了CameraService、AlarmManagerService、VrManagerService等服務。這些服務的父類均為SystemService。

從注釋3、4、5的方法可以看出,官方把系統服務分為了三種類型,分别是引導服務、核心服務和其他服務,其中其他服務是一些非緊要和一些不需要立即啟動的服務。

系統服務總共大約有80多個,我們主要來檢視引導服務AMS是如何啟動的,注釋3處的startBootstrapServices方法如下所示。

frameworks/base/services/java/com/android/server/SystemServer.java
   private void startBootstrapServices() {
        Installer installer = mSystemServiceManager.startService(Installer.class);
        // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();//1
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
      ...
    }
           

在注釋1處調用了SystemServiceManager的startService方法,方法的參數是

ActivityManagerService.Lifecycle.class:

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
  @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
           ...
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);//1
                service = constructor.newInstance(mContext);//2
            } catch (InstantiationException ex) {
              ...
            }
            // Register it.
            mServices.add(service);//3
            // Start it.
            try {
                service.onStart();//4
            } catch (RuntimeException ex) {
                throw new RuntimeException("Failed to start service " + name
                        + ": onStart threw an exception", ex);
            }
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
           

startService方法傳入的參數是Lifecycle.class,Lifecycle繼承自SystemService。

首先,通過反射來建立Lifecycle執行個體,注釋1處得到傳進來的Lifecycle的構造器constructor,在注釋2處調用constructor的newInstance方法來建立Lifecycle類型的service對象。

接着在注釋3處将剛建立的service添加到ArrayList類型的mServices對象中來完成注冊。

最後在注釋4處調用service的onStart方法來啟動service,并傳回該service。Lifecycle是AMS的内部類,代碼如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;
        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);//1
        }
        @Override
        public void onStart() {
            mService.start();//2
        }
        public ActivityManagerService getService() {
            return mService;//3
        }
    }
           

上面的代碼結合SystemServiceManager的startService方法來分析,當通過反射來建立Lifecycle執行個體時,會調用注釋1處的方法建立AMS執行個體,當調用Lifecycle類型的service的onStart方法時,實際上是調用了注釋2處AMS的start方法。在SystemServer的startBootstrapServices方法的注釋1處,調用了如下代碼:

 mActivityManagerService = mSystemServiceManager.startService(

                ActivityManagerService.Lifecycle.class).getService();

我們知道SystemServiceManager的startService方法最終會傳回Lifecycle類型的對象,緊接着又調用了Lifecycle的getService方法,這個方法會傳回AMS類型的mService對象,見注釋3處,這樣AMS執行個體就會被建立并且傳回。

3.AMS與程序啟動

在Android系統啟動流程(二)解析Zygote程序啟動過程這篇文章中,我提到了Zygote的Java架構層中,會建立一個Server端的Socket,這個Socket用來等待AMS來請求Zygote來建立新的應用程式程序。要啟動一個應用程式,首先要保證這個應用程式所需要的應用程式程序已經被啟動。AMS在啟動應用程式時會檢查這個應用程式需要的應用程式程序是否存在,不存在就會請求Zygote程序将需要的應用程式程序啟動。Service的啟動過程中會調用ActiveServices的bringUpServiceLocked方法,如下所示。

        frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
  ...
  final String procName = r.processName;//1
  ProcessRecord app;
  if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//2
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {//3
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode,
                    mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);//4
                    return null;
                } catch (TransactionTooLargeException e) {
              ...
            }
        } else {
            app = r.isolatedProc;
        }
 if (app == null && !permissionsReviewRequired) {//5
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    "service", r.name, false, isolated, false)) == null) {//6
              ...
            }
            if (isolated) {
                r.isolatedProc = app;
            }
        }
 ...     }
           

在注釋1處得到ServiceRecord的processName的值指派給procName ,其中ServiceRecord用來描述Service的android:process屬性。注釋2處将procName和Service的uid傳入到AMS的getProcessRecordLocked方法中,來查詢是否存在一個與Service對應的ProcessRecord類型的對象app,ProcessRecord主要用來記錄運作的應用程式程序的資訊。注釋5處判斷Service對應的app為null則說明用來運作Service的應用程式程序不存在,則調用注釋6處的AMS的startProcessLocked方法來建立對應的應用程式程序, 具體的過程請檢視Android應用程式程序啟動過程(前篇)。

4.AMS家族

        ActivityManager是一個和AMS相關聯的類,它主要對運作中的Activity進行管理,這些管理工作并不是由ActivityManager來處理的,而是交由AMS來處理,ActivityManager中的方法會通過ActivityManagerNative(以後簡稱AMN)的getDefault方法來得到ActivityManagerProxy(以後簡稱AMP),通過AMP就可以和AMN進行通信,而AMN是一個抽象類,它會将功能交由它的子類AMS來處理,是以,AMP就是AMS的代理類。AMS作為系統核心服務,很多API是不會暴露給ActivityManager的,是以ActivityManager并不算是AMS家族一份子。

為了講解AMS家族,這裡拿Activity的啟動過程舉例,Activity的啟動過程中會調用Instrumentation的execStartActivity方法,如下所示。

frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
           

execStartActivity方法中會調用AMN的getDefault來擷取AMS的代理類AMP。接着調用了AMP的startActivity方法,先來檢視AMN的getDefault方法做了什麼,如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//1
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//2
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }+
    };}
           

getDefault方法調用了gDefault的get方法,我們接着往下看,gDefault 是一個Singleton類。注釋1處得到名為”activity”的Service引用,也就是IBinder類型的AMS的引用。接着在注釋2處将它封裝成AMP類型對象,并将它儲存到gDefault中,此後調用AMN的getDefault方法就會直接獲得AMS的代理對象AMP。

注釋2處的asInterface方法如下所示。

    frameworks/base/core/java/android/app/ActivityManagerNative.java

  static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        return new ActivityManagerProxy(obj);}
           

 asInterface方法的主要作用就是将IBinder類型的AMS引用封裝成AMP,AMP的構造方法如下所示。

    frameworks/base/core/java/android/app/ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager{
        public ActivityManagerProxy(IBinder remote)
        {
            mRemote = remote;
        }...
     }
           

AMP的構造方法中将AMS的引用指派給變量mRemote ,這樣在AMP中就可以使用AMS了。 其中IActivityManager是一個接口,AMN和AMP都實作了這個接口,用于實作代理模式和Binder通信。 再回到Instrumentation的execStartActivity方法,來檢視AMP的startActivity方法,AMP是AMN的内部類,代碼如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
           String resolvedType, IBinder resultTo, String resultWho, int requestCode,
           int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
     ...
       data.writeInt(requestCode);
       data.writeInt(startFlags);
     ...
       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
       reply.readException();+
       int result = reply.readInt();
       reply.recycle();
       data.recycle();
       return result;
   }
           

首先會将傳入的參數寫入到Parcel類型的data中。在注釋1處,通過IBinder類型對象mRemote(AMS的引用)向服務端的AMS發送一個START_ACTIVITY_TRANSACTION類型的程序間通信請求。那麼服務端AMS就會從Binder線程池中讀取我們用戶端發來的資料,最終會調用AMN的onTransact方法,如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

   @Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
           throws RemoteException {
       switch (code) {
       case START_ACTIVITY_TRANSACTION:
       {
       ...
           int result = startActivity(app, callingPackage, intent, resolvedType,
                   resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
           reply.writeNoException();
           reply.writeInt(result);
           return true;
       }
   }
           

onTransact中會調用AMS的startActivity方法,如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Override
 public final int startActivity(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
             resultWho, requestCode, startFlags, profilerInfo, bOptions,
             UserHandle.getCallingUserId());
 }
           

startActivity方法會最後return startActivityAsUser方法,如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Override
 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
     enforceNotIsolatedCaller("startActivity");
     userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
             userId, false, ALLOW_FULL_ONLY, "startActivity", null);
     return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
             profilerInfo, null, null, bOptions, false, userId, null, null);
  }           
           

startActivityAsUser方法最後會return ActivityStarter的startActivityMayWait方法,這一調用過程已經脫離了本節要講的AMS家族,是以這裡不做介紹了,具體的調用過程可以檢視Android深入四大元件(一)應用程式啟動過程(後篇)這篇文章。

在Activity的啟動過程中提到了AMP、AMN和AMS,它們共同組成了AMS家族的主要部分,如下圖所示。

AMP是AMN的内部類,它們都實作了IActivityManager接口,這樣它們就可以實作代理模式,具體來講是遠端代理:AMP和AMN是運作在兩個程序的,AMP是Client端,AMN則是Server端,而Server端中具體的功能都是由AMN的子類AMS來實作的,是以,AMP就是AMS在Client端的代理類。AMN又實作了Binder類,這樣AMP可以和AMS就可以通過Binder來進行程序間通信。

ActivityManager通過AMN的getDefault方法得到AMP,通過AMP就可以和AMN進行通信,也就是間接的與AMS進行通信。除了ActivityManager,其他想要與AMS進行通信的類都需要通過AMP,如下圖所示。

PMS之前言

PMS的建立過程分為兩個部分進行講解,分别是SyetemServer處理部分和PMS構造方法。其中SyetemServer處理部分和AMS和WMS的建立過程是類似的,可以将它們進行對比,這樣可以更好的了解和記憶這一知識點。

1. PMS之SyetemServer處理部分

PMS是在SyetemServer程序中被建立的,SyetemServer程序用來建立系統服務,不了解它的可以檢視Android系統啟動流程(三)解析SyetemServer程序啟動過程這篇文章。 從SyetemServer的入口方法main方法開始講起,如下所示。frameworks/base/services/java/com/android/server/SystemServer.java

 public static void main(String[] args) {
        new SystemServer().run();
    }
main方法中隻調用了SystemServer的run方法,如下所示。

frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
    try {
        ...
        //建立消息Looper
         Looper.prepareMainLooper();
        //加載了動态庫libandroid_servers.so
        System.loadLibrary("android_servers");//1
        performPendingShutdown();
        // 建立系統的Context
        createSystemContext();
        // 建立SystemServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd(); 
    }
    try {
        traceBeginAndSlog("StartServices");
        //啟動引導服務
        startBootstrapServices();//3
        //啟動核心服務
        startCoreServices();//4
        //啟動其他服務
        startOtherServices();//5
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }
    ...}
           

在注釋1處加載了動态庫libandroid_servers.so。接下來在注釋2處建立SystemServiceManager,它會對系統的服務進行建立、啟動和生命周期管理。在注釋3中的startBootstrapServices方法中用SystemServiceManager啟動了ActivityManagerService、PowerManagerService、PackageManagerService等服務。

在注釋4處的startCoreServices方法中則啟動了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService。注釋5處的startOtherServices方法中啟動了CameraService、AlarmManagerService、VrManagerService等服務。這些服務的父類均為SystemService。

從注釋3、4、5的方法可以看出,官方把系統服務分為了三種類型,分别是引導服務、核心服務和其他服務,其中其他服務是一些非緊要和一些不需要立即啟動的服務。這些系統服務總共有100多個,我們熟知的AMS屬于引導服務,WMS屬于其他服務,

本文要講的PMS屬于引導服務,是以這裡列出引導服務以及它們的作用,見下表。

引導服務  作用
Installer   系統安裝apk時的一個服務類,啟動完成Installer服務之後才能啟動其他的系統服務
ActivityManagerService    負責四大元件的啟動、切換、排程。
PowerManagerService    計算系統中和Power相關的計算,然後決策系統應該如何反應
LightsService     管理和顯示背光LED
DisplayManagerService    用來管理所有顯示裝置
UserManagerService  多使用者模式管理
SensorService 為系統提供各種感應器服務
PackageManagerService  用來對apk進行安裝、解析、删除、解除安裝等等操作

檢視啟動引導服務的注釋3處的startBootstrapServices方法。

frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    ...
    traceBeginAndSlog("StartPackageManagerService");
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//1
    mFirstBoot = mPackageManagerService.isFirstBoot();//2
    mPackageManager = mSystemContext.getPackageManager();
    traceEnd();
    ...}
           

注釋1處的PMS的main方法主要用來建立PMS,其中最後一個參數mOnlyCore代表是否隻掃描系統的目錄,它在本篇文章中會出現多次,一般情況下它的值為false。注釋2處擷取boolean類型的變量mFirstBoot,它用于表示PMS是否首次被啟動。mFirstBoot是後續WMS建立時所需要的參數,從這裡就可以看出系統服務之間是有依賴關系的,它們的啟動順序不能随意被更改。

2. PMS構造方法

PMS的main方法如下所示。

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

   public static PackageManagerService main(Context context, Installer installer,

            boolean factoryTest, boolean onlyCore) {

        PackageManagerServiceCompilerMapping.checkProperties();

        PackageManagerService m = new PackageManagerService(context, installer,

                factoryTest, onlyCore);

        m.enableSystemUserPackages();

        ServiceManager.addService("package", m);

        return m;

    }

main方法主要做了兩件事,一個是建立PMS對象,另一個是将PMS注冊到ServiceManager中。 PMS的構造方法大概有600多行,分為5個階段,每個階段會列印出相應的EventLog,EventLog用于列印

Android系統的事件日志。

1.BOOT_PROGRESS_PMS_START(開始階段)

2.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START(掃描系統階段)

3.BOOT_PROGRESS_PMS_DATA_SCAN_START(掃描Data分區階段)

4.BOOT_PROGRESS_PMS_SCAN_END(掃描結束階段)

5.BOOT_PROGRESS_PMS_READY(準備階段)

2.1 開始階段

PMS的構造方法中會擷取一些包管理需要屬性,如下所示。frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
        //列印開始階段日志
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis())
        ...
        //用于存儲螢幕的相關資訊
        mMetrics = new DisplayMetrics();
        //Settings用于儲存所有包的動态設定
        mSettings = new Settings(mPackages);
        //在Settings中添加多個預設的sharedUserId
        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);//1
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        ...
        mInstaller = installer;
        //建立Dex優化工具類
        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                FgThread.get().getLooper());
        getDefaultDisplayMetrics(context, mMetrics);
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
        //得到全局系統配置資訊。
        SystemConfig systemConfig = SystemConfig.getInstance();
        //擷取全局的groupId 
        mGlobalGids = systemConfig.getGlobalGids();
        //擷取系統權限
        mSystemPermissions = systemConfig.getSystemPermissions();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        mProtectedPackages = new ProtectedPackages(mContext);
        //安裝APK時需要的鎖,保護所有對installd的通路。
        synchronized (mInstallLock) {//1
        //更新APK時需要的鎖,保護記憶體中已經解析的包資訊等内容
        synchronized (mPackages) {//2
            //建立背景線程ServiceThread
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            //建立PackageHandler綁定到ServiceThread的消息隊列
            mHandler = new PackageHandler(mHandlerThread.getLooper());//3
            mProcessLoggingHandler = new ProcessLoggingHandler();
            //将PackageHandler添加到Watchdog的檢測集中
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);//4

        mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
        mInstantAppRegistry = new InstantAppRegistry(this);
        //在Data分區建立一些目錄
        File dataDir = Environment.getDataDirectory();//5
        mAppInstallDir = new File(dataDir, "app");
        mAppLib32InstallDir = new File(dataDir, "app-lib");
        mAsecInternalPath = new File(dataDir, "app-asec").getPath();
        mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
        //建立多使用者管理服務
        sUserManager = new UserManagerService(context, this,
                new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
         ...
           mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false))//6
      ...     }
           

在開始階段中建立了很多PMS中的關鍵對象并指派給PMS中的成員變量,下面簡單介紹這些成員變量。

mSettings 用于儲存所有包的動态設定。注釋1處将系統程序的sharedUserId添加到Settings中,sharedUserId用于程序間共享資料,比如兩個App的之間的資料是不共享的,如果它們有了共同的sharedUserId,就可以運作在同一個程序中共享資料。
mInstaller Installer繼承自SystemService,和PMS、AMS一樣是系統的服務(雖然名稱不像是服務),PMS很多的操作都是由Installer來完成的,比如APK的安裝和解除安裝。在Installer内部,通過IInstalld和installd進行Binder通信,由位于nativie層的installd來完成具體的操作。
systemConfig 用于得到全局系統配置資訊。比如系統的權限就可以通過SystemConfig來擷取。 
mPackageDexOptimizer Dex優化的工具類。
mHandler(PackageHandler類型) PackageHandler繼承自Handler,在注釋3處它綁定了背景線程ServiceThread的消息隊列。PMS通過PackageHandler驅動APK的複制和安裝工作,具體的請看在Android包管理機制(三)PMS處理APK的安裝這篇文章。

PackageHandler處理的消息隊列如果過于繁忙,有可能導緻系統卡住, 是以在注釋4處将它添加到Watchdog的監測集中。

Watchdog主要有兩個用途,一個是定時檢測系統關鍵服務(AMS和WMS等)是否可能發生死鎖,還有一個是定時檢測線程的消息隊列是否長時間處于工作狀态(可能阻塞等待了很長時間)。如果出現上述問題,Watchdog會将日志儲存起來,必要時還會殺掉自己所在的程序,也就是SystemServer程序。

sUserManager(UserManagerService類型) :多使用者管理服務。

除了建立這些關鍵對象,在開始階段還有一些關鍵代碼需要去講解:

注釋1處和注釋2處加了兩個鎖,其中mInstallLock是安裝APK時需要的鎖,保護所有對installd的通路;

mPackages是更新APK時需要的鎖,保護記憶體中已經解析的包資訊等内容。

注釋5處後的代碼建立了一些Data分區中的子目錄,比如/data/app。
注釋6處會解析packages.xml等檔案的資訊,儲存到Settings的對應字段中。packages.xml中記錄系統中所有安裝的應用資訊,包括基本資訊、簽名和權限。如果packages.xml有安裝的應用資訊,那麼注釋6處Settings的readLPw方法會傳回true,mFirstBoot的值為false,說明PMS不是首次被啟動。

2.2 掃描系統階段

...public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {...
            //列印掃描系統階段日志
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);
            ...
            //在/system中建立framework目錄
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            ...
            //掃描/vendor/overlay目錄下的檔案
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
            //掃描/system/framework 目錄下的檔案
            scanDirTracedLI(frameworkDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED,
                    scanFlags | SCAN_NO_DEX, 0);
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            //掃描 /system/priv-app 目錄下的檔案
            scanDirTracedLI(privilegedAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
            //掃描/system/app 目錄下的檔案
            scanDirTracedLI(systemAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
            File vendorAppDir = new File("/vendor/app");
            try {
                vendorAppDir = vendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            //掃描 /vendor/app 目錄下的檔案
            scanDirTracedLI(vendorAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

       //掃描/oem/app 目錄下的檔案
        final File oemAppDir = new File(Environment.getOemDirectory(), "app");
        scanDirTracedLI(oemAppDir, mDefParseFlags
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

        //這個清單代表有可能有更新包的系統App
        final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();//1
        if (!mOnlyCore) {
            Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
            while (psit.hasNext()) {
                PackageSetting ps = psit.next();                 
                if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    continue;
                }
                //這裡的mPackages的是PMS的成員變量,代表scanDirTracedLI方法掃描上面那些目錄得到的 
                final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                if (scannedPkg != null) {           
                    if (mSettings.isDisabledSystemPackageLPr(ps.name)) {//2
                       ...
                        //将這個系統App的PackageSetting從PMS的mPackages中移除
                        removePackageLI(scannedPkg, true);
                        //将更新包的路徑添加到mExpectingBetter清單中
                        mExpectingBetter.put(ps.name, ps.codePath);
                    }
                    continue;
                }
               
                if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                   ...   
                } else {
                    final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
                    //這個系統App更新包資訊在mDisabledSysPackages中,但是沒有發現這個更新包存在
                    if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {//5
                        possiblyDeletedUpdatedSystemApps.add(ps.name);//
                    }
                }
            }
        }
        ...        }
           

/system可以稱作為System分區,裡面主要存儲谷歌和其他廠商提供的Android系統相關檔案和架構。

Android系統架構分為應用層、應用架構層、系統運作庫層(Native 層)、硬體抽象層(HAL層)和Linux核心層,除了Linux核心層在Boot分區,其他層的代碼都在System分區。下面列出 System分區的部分子目錄。

上面的代碼還涉及到/vendor 目錄,它用來存儲廠商對Android系統的定制部分。

系統掃描階段的主要工作有以下3點:

1.建立/system的子目錄,比如/system/framework、/system/priv-app和/system/app等等

2.掃描系統檔案,比如/vendor/overlay、/system/framework、/system/app等等目錄下的檔案。

3.對掃描到的系統檔案做後續處理。

主要來說第3點,一次OTA更新對于一個系統App會有三種情況:

1這個系統APP無更新。

2這個系統APP有更新。

3新的OTA版本中,這個系統APP已經被删除。

當系統App更新,PMS會将該系統App的更新包設定資料(PackageSetting)存儲到Settings的mDisabledSysPackages清單中(具體見PMS的replaceSystemPackageLIF方法),mDisabledSysPackages的類型為ArrayMap<String, PackageSetting>。

mDisabledSysPackages中的資訊會被PMS儲存到packages.xml中的标簽下(具體見Settings的writeDisabledSysPackageLPr方法)。

注釋2處說明這個系統App有更新包,那麼就将該系統App的PackageSetting從mDisabledSysPackages清單中移除,并将系統App的更新包的路徑添加到mExpectingBetter清單中,mExpectingBetter的類型為ArrayMap<String, File>等待後續處理。

注釋5處如果這個系統App的更新包資訊存儲在mDisabledSysPackages清單中,但是沒有發現這個更新包存在,則将它加入到possiblyDeletedUpdatedSystemApps清單中,意為“系統App的更新包可能被删除”,之是以是“可能”,是因為系統還沒有掃描Data分區,隻能暫放到possiblyDeletedUpdatedSystemApps清單中,等到掃描完Data分區後再做處理。

2.3 掃描Data分區階段

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
    ...        
    mSettings.pruneSharedUsersLPw();
    //如果不是隻掃描系統的目錄,那麼就開始掃描Data分區。
    if (!mOnlyCore) {
        //列印掃描Data分區階段日志
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());
        //掃描/data/app目錄下的檔案       
        scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
        //掃描/data/app-private目錄下的檔案   
        scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
                | PackageParser.PARSE_FORWARD_LOCK,
                scanFlags | SCAN_REQUIRE_KNOWN, 0);
        //掃描完Data分區後,處理possiblyDeletedUpdatedSystemApps清單
        for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
            PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
            // 從mSettings.mDisabledSysPackages變量中移除去此應用
            mSettings.removeDisabledSystemPackageLPw(deletedAppName);
            String msg;
          //1:如果這個系統App的包資訊不在PMS的變量mPackages中,說明是殘留的App資訊,後續會删除它的資料。
            if (deletedPkg == null) {
                msg = "Updated system package " + deletedAppName
                        + " no longer exists; it's data will be wiped";
                // Actual deletion of code and data will be handled by later
                // reconciliation step
            } else {
            //2:如果這個系統App在mPackages中,說明是存在于Data分區,不屬于系統App,那麼移除其系統權限。
                msg = "Updated system app + " + deletedAppName
                        + " no longer present; removing system privileges for "
                        + deletedAppName;
                deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
                deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
            }
            logCriticalInfo(Log.WARN, msg);
        }
         //周遊mExpectingBetter清單
        for (int i = 0; i < mExpectingBetter.size(); i++) {
            final String packageName = mExpectingBetter.keyAt(i);
            if (!mPackages.containsKey(packageName)) {
                //得到系統App的更新包路徑
                final File scanFile = mExpectingBetter.valueAt(i);
                logCriticalInfo(Log.WARN, "Expected better " + packageName
                        + " but never showed up; reverting to system");
                int reparseFlags = mDefParseFlags;
                //3:根據系統App所在的目錄設定掃描的解析參數
                if (FileUtils.contains(privilegedAppDir, scanFile)) {
                    reparseFlags = PackageParser.PARSE_IS_SYSTEM
                            | PackageParser.PARSE_IS_SYSTEM_DIR
                            | PackageParser.PARSE_IS_PRIVILEGED;
                } 
                ...
                //将packageName對應的包設定資料(PackageSetting)添加到mSettings的mPackages中
                mSettings.enableSystemPackageLPw(packageName);//4
                try {
                    //掃描系統App的更新包
                    scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);//5
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse original system package: "
                            + e.getMessage());
                }
            }
        }
    }
   //清除mExpectingBetter清單
    mExpectingBetter.clear();...}
           

/data可以稱為Data分區,它用來存儲所有使用者的個人資料和配置檔案。下面列出Data分區部分子目錄: 掃描Data分區階段主要做了以下幾件事:

1.掃描/data/app和/data/app-private目錄下的檔案。

2.周遊possiblyDeletedUpdatedSystemApps清單,注釋1處如果這個系統App的包資訊不在PMS的變量mPackages中,說明是殘留的App資訊,後續會删除它的資料。注釋2處如果這個系統App的包資訊在mPackages中,說明是存在于Data分區,不屬于系統App,那麼移除其系統權限。

3.周遊mExpectingBetter清單,注釋3處根據系統App所在的目錄設定掃描的解析參數,注釋4處的方法内部會将packageName對應的包設定資料(PackageSetting)添加到mSettings的mPackages中。注釋5處掃描系統App的更新包,最後清除mExpectingBetter清單。

2.4 掃描結束階段

  //列印掃描結束階段日志
  EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");
            int updateFlags = UPDATE_PERMISSIONS_ALL;
            // 如果目前平台SDK版本和上次啟動時的SDK版本不同,重新更新APK的授權
            if (ver.sdkVersion != mSdkVersion) {
                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                        + mSdkVersion + "; regranting permissions for internal storage");
                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
            }
            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
            ver.sdkVersion = mSdkVersion;
           //如果是第一次啟動或者是Android M更新後的第一次啟動,需要初始化所有使用者定義的預設首選App
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                    applyFactoryDefaultBrowserLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }
           ...
            //OTA後的第一次啟動,會清除代碼緩存目錄。
            if (mIsUpgrade && !onlyCore) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < mSettings.mPackages.size(); i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }
            ...
           // 把Settings的内容儲存到packages.xml中
            mSettings.writeLPr();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
           

掃描結束結束階段主要做了以下幾件事:

1.如果目前平台SDK版本和上次啟動時的SDK版本不同,重新更新APK的授權。

2.如果是第一次啟動或者是Android M更新後的第一次啟動,需要初始化所有使用者定義的預設首選App。

3.OTA更新後的第一次啟動,會清除代碼緩存目錄。

4.把Settings的内容儲存到packages.xml中,這樣此後PMS再次建立時會讀到此前儲存的Settings的内容。

2.5 準備階段

 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                SystemClock.uptimeMillis());
    ... 
    mInstallerService = new PackageInstallerService(context, this);//1
    ...
    Runtime.getRuntime().gc();//2
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
    FallbackCategoryProvider.loadFallbacks();
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    mInstaller.setWarnIfHeld(mPackages);
    LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());//3
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}
           
注釋1處建立PackageInstallerService,PackageInstallerService是用于管理安裝會話的服務,它會為每次安裝過程配置設定一個SessionId,在Android包管理機制(二)PackageInstaller安裝APK這篇文章中提到過PackageInstallerService。
注釋2處進行一次垃圾收集。注釋3處将PackageManagerInternalImpl(PackageManager的本地服務)添加到LocalServices中,LocalServices用于存儲運作在目前的程序中的本地服務。

2.Activity 啟動流程,App 啟動流程

Activity的啟動模式

1.standard:預設标準模式,每啟動一個都會建立一個執行個體,

2.singleTop:棧頂複用,如果在棧頂就調用onNewIntent複用,從onResume()開始

3.singleTask:棧内複用,本棧内隻要用該類型Activity就會将其頂部的activity出棧

4.singleInstance:單例模式,除了3中特性,系統會單獨給該Activity建立一個棧,

1.什麼是Zygote程序

1.1 簡單介紹

Zygote程序是所有的android程序的父程序,包括SystemServer和各種應用程序都是通過Zygote程序fork出來的。Zygote(孵化)程序相當于是android系統的根程序,後面所有的程序都是通過這個程序fork出來的

雖然Zygote程序相當于Android系統的根程序,但是事實上它也是由Linux系統的init程序啟動的。

1.2 各個程序的先後順序

init程序 --> Zygote程序 --> SystemServer程序 -->各種應用程序

1.3 程序作用說明

init程序:linux的根程序,android系統是基于linux系統的,是以可以算作是整個android作業系統的第一個程序;

Zygote程序:android系統的根程序,主要作用:可以作用Zygote程序fork出SystemServer程序和各種應用程序;

SystemService程序:主要是在這個程序中啟動系統的各項服務,比如ActivityManagerService,PackageManagerService,WindowManagerService服務等等;

各種應用程序:啟動自己編寫的用戶端應用時,一般都是重新啟動一個應用程序,有自己的虛拟機與運作環境;

2.Zygote程序的啟動流程

2.1 源碼位置

位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

Zygote程序mian方法主要執行邏輯:

初始化DDMS;

注冊Zygote程序的socket通訊;

初始化Zygote中的各種類,資源檔案,OpenGL,類庫,Text資源等等;

初始化完成之後fork出SystemServer程序;

fork出SystemServer程序之後,關閉socket連接配接;

2.2 ZygoteInit類的main方法

init程序在啟動Zygote程序時一般都會調用ZygoteInit類的main方法,是以這裡看一下該方法的具體實作(基于android23源碼);

調用enableDdms(),設定DDMS可用,可以發現DDMS啟動的時機還是比較早的,在整個Zygote程序剛剛開始要啟動額時候就設定可用。

之後初始化各種參數

通過調用registerZygoteSocket方法,注冊為Zygote程序注冊Socket

然後調用preload方法實作預加載各種資源

然後通過調用startSystemServer開啟SystemServer服務,這個是重點

public static void main(String argv[]) {
    try {
        //設定ddms可以用
        RuntimeInit.enableDdms();
        SamplingProfilerIntegration.start();
        boolean startSystemServer = false;
        String socketName = "zygote";
        String abiList = null;
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                socketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

    if (abiList == null) {
        throw new RuntimeException("No ABI list supplied.");
    }

    registerZygoteSocket(socketName);
    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
        SystemClock.uptimeMillis());
    preload();
    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
        SystemClock.uptimeMillis());
    SamplingProfilerIntegration.writeZygoteSnapshot();

    gcAndFinalize();
    Trace.setTracingEnabled(false);

    if (startSystemServer) {
        startSystemServer(abiList, socketName);
    }

    Log.i(TAG, "Accepting command socket connections");
    runSelectLoop(abiList);

    closeServerSocket();
} catch (MethodAndArgsCaller caller) {
    caller.run();
} catch (RuntimeException ex) {
    Log.e(TAG, "Zygote died with exception", ex);
    closeServerSocket();
    throw ex;
}
}
           

2.3 registerZygoteSocket(socketName)分析

調用registerZygoteSocket(String socketName)為Zygote程序注冊socket
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) {
            throw new RuntimeException(fullSocketName + " unset or invalid", 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);
        }
    }
}
           

2.4 preLoad()方法分析

源碼如下所示

static void preload() {
    Log.d(TAG, "begin preload");
    preloadClasses();
    preloadResources();
    preloadOpenGL();
    preloadSharedLibraries();
    preloadTextResources();
    // Ask the WebViewFactory to do any initialization that must run in the zygote process,
    // for memory sharing purposes.
    WebViewFactory.prepareWebViewInZygote();
    Log.d(TAG, "end preload");
}
           

大概操作是這樣的:

  1. preloadClasses()用于初始化Zygote中需要的class類;
  2. preloadResources()用于初始化系統資源;
  3. preloadOpenGL()用于初始化OpenGL;
  4. preloadSharedLibraries()用于初始化系統libraries;
  5. preloadTextResources()用于初始化文字資源;
  6. prepareWebViewInZygote()用于初始化webview;

2.5 startSystemServer()啟動程序

private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_BLOCK_SUSPEND,
        OsConstants.CAP_KILL,
        OsConstants.CAP_NET_ADMIN,
        OsConstants.CAP_NET_BIND_SERVICE,
        OsConstants.CAP_NET_BROADCAST,
        OsConstants.CAP_NET_RAW,
        OsConstants.CAP_SYS_MODULE,
        OsConstants.CAP_SYS_NICE,
        OsConstants.CAP_SYS_RESOURCE,
        OsConstants.CAP_SYS_TIME,
        OsConstants.CAP_SYS_TTY_CONFIG
    );
    /* Hardcoded command line to start the system server */
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        /* 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) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        handleSystemServerProcess(parsedArgs);
    }

    return true;
}
           

這段邏輯的執行邏輯就是通過Zygote fork出SystemServer程序

3.SystemServer程序啟動流程

3.1 SystemServer程序簡介

SystemServer程序主要的作用是在這個程序中啟動各種系統服務,比如ActivityManagerService, PackageManagerService,WindowManagerService服務,以及各種系統性的服務其實都是在SystemServer程序中啟動的,而當我們的應用需要使用各種系統服務的時候其實也是通過與SystemServer程序通訊擷取各種服務對象的句柄的。

3.2 SystemServer的main方法

如下所示,比較簡單,隻是new出一個SystemServer對象并執行其run方法,檢視SystemServer類的定義我們知道其實final類型的,是以我們一般不能重寫或者繼承。

繼續閱讀