AMS分析「 AMS啟動流程 」

? ActivityManagerService服務是Android系統(tǒng)核心服務,負責Android管理系統(tǒng)Activity,Service,ContentProvider和BroadcastReceiver 四大組件,同時還負責Android系統(tǒng)中的進程管理。由此可見ActivityManagerService服務對于Android系統(tǒng)來講非常重要,我們就從以下幾個方面來了解下AMS服務。

  1. AMS服務的啟動和初始化過程
  2. AMS如何啟動和管理Activity
  3. AMS如何啟動和管理Service
  4. AMS如何管理BroadCastReceiver
  5. AMS如何管理ContentProvider
    此篇文章就來總結下Ams服務的啟動和初始化過程。

ActivityManagerService的啟動和初始化過程

系統(tǒng)進程運行環(huán)境的初始化

在分析AMS服務之前我們先來了解下什么是Context.
Context是什么?
Context是一個抽象類,其通用實現(xiàn)在ContextImpl類中。是一個訪問application環(huán)境全局信息的接口,通過它可以訪問application的資源和相關的類,其主要功能如下:

? 啟動Activity
? 啟動和停止Service
? 發(fā)送廣播消息(Intent)
? 注冊廣播消息(Intent)接收者
? 可以訪問APK中各種資源(如Resources和AssetManager等)
? 可以訪問Package的相關信息
? APK的各種權限管理

對你的應用程序而言,Context就是一個無所不知的大管家,大家需要什么,直接問它就可以了。


Context實現(xiàn)

Context的類關系圖可知,ContextImpl最終實現(xiàn)了Context相關方法,ContextWrapper只是一個代理類,Activity,Service,Application都是實現(xiàn)了ContextWrapper,所以在Activity,Service和Application中調(diào)用的context的相關方法,最終都有ContextImpl來實現(xiàn)。而ContextImpl最終是應用程序的大管家,管理著操作本應用的相關方法。

?Android系統(tǒng)中的進程分為兩種,應用進程和系統(tǒng)進程。而ActivityThread就是應用進程的主線程,Android系統(tǒng)的應用進程啟動后首先運行ActivityThread的main函數(shù),ActivityThread和AMS進行通信,調(diào)度和執(zhí)行應用進程的四大組件。

?SystemServer是Android的系統(tǒng)進程,由于系統(tǒng)進程中也有一些Activity和系統(tǒng)資源,為了保證調(diào)用方式統(tǒng)一,系統(tǒng)進程也需要ActivityThread和Context等Android運行環(huán)境。所以SystemServer也是一個特殊的應用進行。

對Android而言系統(tǒng)進程而言,SysrtemServer也是一個特別的應用程序,也有自己的Context上下文環(huán)境,而系統(tǒng)的Context又是怎么創(chuàng)建的呢?

它是SystemServer啟動之后,在createSystemContext方法中創(chuàng)建的。

private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        ……
    }

第一步ActivityThread.systemMain方法,該方法生成了一個ActivityThread對象。

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

首先創(chuàng)建了一個ActivityThread對象,然后調(diào)用attach方法。
ActivityThread的構造方法很簡單就是創(chuàng)建了一個ResourcesManager對象,用于管理應用程序中的資源文件
那就接著看ActivityThread的Attach方法。

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
    ……
        }else{
        //修改系統(tǒng)進程的名稱為system_process
    android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                //創(chuàng)建一個該進程相關的context對象
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
 
}

?attach方法傳進來的參數(shù)為true,代表該進程為系統(tǒng)進程,所以直接看else中的方法實現(xiàn)。
?首先調(diào)用setAppName將系統(tǒng)應用的名稱改為system_process,調(diào)試的時候我們可以看到系統(tǒng)的進程名稱為system_process.
?然后創(chuàng)建了一個Instrumentation類,該類是一個工具類,ActivityThread接收到AMS的指令創(chuàng)建和調(diào)度交互都由它來執(zhí)行。
?然后調(diào)用createAppContext來創(chuàng)建一個系統(tǒng)的ContextImpl的大管家,傳入的關鍵參數(shù)為系統(tǒng)進程的apk相關信息。后面再分析getSystemContext方法,然后創(chuàng)建了一個android,app.application,并調(diào)用了它的onCreate方法。
getSystemContext方法
systemContext最終由ContextImpl.createSystemContext方法來創(chuàng)建。

static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetricsLocked());
        return context;
    }

首先創(chuàng)建了一個LoadedApk對象,然后根據(jù)LoadedApk對象創(chuàng)建了一個ContextImpl對象。
LoadedApk代表一個加載到系統(tǒng)中的APK。 其中保存了apk的基本信息

LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread;
        mApplicationInfo = new ApplicationInfo();
        mApplicationInfo.packageName = "android";
        mPackageName = "android";
        mAppDir = null;
        mResDir = null;
        mSplitAppDirs = null;
        mSplitResDirs = null;
        mOverlayDirs = null;
        mSharedLibraries = null;
        mDataDir = null;
        mDataDirFile = null;
        mLibDir = null;
        mBaseClassLoader = null;
        mSecurityViolation = false;
        mIncludeCode = true;
        mRegisterPackage = false;
        mClassLoader = ClassLoader.getSystemClassLoader();
        mResources = Resources.getSystem();
    }

LoadedAPK的這個構造方法只有系統(tǒng)進程創(chuàng)建的時候可以調(diào)用。它代表一個系統(tǒng)進程的apk,它里面存儲著資源文件的位置,jni包的位置等信息,包名為android。其實代表的就是就是framework-res.apk。該apk僅供systemServer使用。

private ContextImpl(ContextImpl container, ActivityThread mainThread,
            LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
            Display display, Configuration overrideConfiguration, int createDisplayWithId) {
        mOuterContext = this;
        //framework-res.apk的主進程為當前的ActivityThread
        mMainThread = mainThread;
        mActivityToken = activityToken;
        mRestricted = restricted;
 
        if (user == null) {
            user = Process.myUserHandle();
        }
        mUser = user;
        //packageinfo的信息
        mPackageInfo = packageInfo;
        //初始化資源管理器
        mResourcesManager = ResourcesManager.getInstance();
 
      ……
ResourcesManager.getInstance().getAdjustedDisplay(displayId, mDisplayAdjustments);
 
        Resources resources = packageInfo.getResources(mainThread);
        if (resources != null) {
            if (displayId != Display.DEFAULT_DISPLAY
                    || overrideConfiguration != null
                    || (compatInfo != null && compatInfo.applicationScale
                            != resources.getCompatibilityInfo().applicationScale)) {
                resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
                        packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
                        packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
                        overrideConfiguration, compatInfo);
            }
        }
        mResources = resources;
……
        //初始化系統(tǒng)的contentResolver
        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
    }

?調(diào)用ContextImpl的構造方法生成了一個ContextImpl。該構造方法主要就是初始化了ContextImpl中的一些信息,如ResourManager等。同時將剛才創(chuàng)建的LoadAPK的package信息保存到的Context中,最終生成了一個和系統(tǒng)進程相關的Context。因為它保存了系統(tǒng)相關的信息

?調(diào)用systemMain函數(shù)結束后,首先生成了一個ActivityThread對象,它代表應用進程的主線程。得到一個Context對象,它背后所指向的Application環(huán)境與framework-res.apk有關。

?這兩樣東西就構成了Android程序的運行環(huán)境。我們自己寫的apk的代碼最終在ActivityThread線程上運行,通過Context應用程序的大管家,可以調(diào)用進程所用到的資源和方法。

?為什么要為系統(tǒng)進程設置應用的運行環(huán)境呢,因為系統(tǒng)進程中包含了一個framewrok-res.apk的應用進程,這個apk也需要一個運行環(huán)境。

?在SystemServer進程中也創(chuàng)建了一個Android運行環(huán)境,說明SystemServer系統(tǒng)進程也被看做一個特殊的應用程序。因為系統(tǒng)進程中也會有Activity界面和資源,所以也為他創(chuàng)建了一個運行環(huán)境,這樣做它就可以和普通應用進程一樣使用統(tǒng)一的接口和系統(tǒng)交互了。

了解了系統(tǒng)Context的創(chuàng)建步驟及系統(tǒng)運行環(huán)境的概念,我們就一步一步的來分析AMS啟動和初始化的過程,首先分析啟動AMS服務。
AMS服務的啟動過程和其他系統(tǒng)服務的啟動過程一樣,也是在SystemServer服務中啟動起來的。首先來看SystemServer中關于ActivityManagerService的一些相關的方法。

AMS服務的啟動過程

private void startBootstrapServices() {
        // Activity manager runs the show.
     mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
 
 
     mActivityManagerService.setSystemProcess();
……
     mActivityManagerService.installSystemProviders();
 
……
     mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                Slog.i(TAG, "Making services ready");
                mSystemServiceManager.startBootPhase(
                        SystemService.PHASE_ACTIVITY_MANAGER_READY);
 
                try {
                    mActivityManagerService.startObservingNativeCrashes();
                } catch (Throwable e) {
                    reportWtf("observing native crashes", e);
                }

上面的的幾個方法就是SystemServer中關于AMS啟動時的幾個關鍵方法,主要分為4個步驟

1:創(chuàng)建AMS對象,并啟動服務
2:將AMS所在的系統(tǒng)進程,添加到進程管理中去
3:為系統(tǒng)進程安裝ContentProvider對象
4:在systemReady方法中做善后操作

一個一個的來看先這些方法的作用,這些方法就是AMS的啟動和初始化過程。

啟動ActivityManagerService的方法

mActivityManagerService = mSystemServiceManager.startService(
          ActivityManagerService.Lifecycle.class).getService();

AMS服務同樣是通過SystemServiceManager來啟動的。那我們首先來看ActivityManagerService.Lifecycle的構造方法,然后在來看它的Start函數(shù)。
Lifecycle的構造方法中很簡單就是構造一個AMS的對象

mService = new ActivityManagerService(context);

創(chuàng)建AMS對象的時候需要傳遞一個Context作為參數(shù),那這個mSystemContext是就是上面創(chuàng)建的系統(tǒng)Context。
接著看AMS的構造方法。

public ActivityManagerService(Context systemContext) {
//系統(tǒng)的context        
mContext = systemContext;
    //獲得系統(tǒng)的ActivityThread
        mSystemThread = ActivityThread.currentActivityThread();
    //創(chuàng)建一個HandlerThread用來處理AMS接收的命令
        mHandlerThread = new ServiceThread(TAG,
                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        mHandler = new MainHandler(mHandlerThread.getLooper());
        mUiHandler = new UiHandler();
    //初始化廣播的隊列
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", BROADCAST_FG_TIMEOUT, false);
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", BROADCAST_BG_TIMEOUT, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
    //初始化Service相關的容器
        mServices = new ActiveServices(this);
    //初始化Provider相關的Map,里面保存了注冊的ContentProvider
        mProviderMap = new ProviderMap(this);
 
        //初始化并創(chuàng)建data/system/目錄
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        systemDir.mkdirs();
    //初始化電量統(tǒng)計服務相關的信息
        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.scheduleWriteToDisk();
        mOnBattery = DEBUG_POWER ? true
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
    //初始化系統(tǒng)統(tǒng)計服務,用于統(tǒng)計系統(tǒng)的運行信息
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
 
        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
 
        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
 
        //創(chuàng)建系統(tǒng)的第一個user,userID為0,該用戶具有管理員權限
        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
        mUserLru.add(UserHandle.USER_OWNER);
        updateStartedUserArrayLocked();
    //獲取opengle的版本
        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
 
        //初始化字體語言等配置信息
        mConfiguration.setToDefaults();
        mConfiguration.setLocale(Locale.getDefault());
 
     ……;
        mRecentTasks = new RecentTasks(this);
    //初始化StackSupervisor,該類是Activity啟動和調(diào)度的核心類
        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);

從代碼中可以看出,AMS的構造方法主要是在做一些初始化的先關操作。先保存了自己的運行環(huán)境的Context和ActivityThread。AMS負責調(diào)度四大組件,所以會初始化broadcast,service和contentProvider相關的變量,接著初始化了電量統(tǒng)計服務,創(chuàng)建了系統(tǒng)的第一個用戶,初始化了基本的配置信息,還創(chuàng)建了Activity調(diào)度的核心類,因為Activity調(diào)度比較復雜,Activity相關的信息初始化會在ActivityStackSupervisor中。

AMS的start方法。

    private void start() {
        mProcessCpuThread.start();
        mBatteryStatsService.publish(mContext);
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }

AMS的start方法很簡單,只是啟動了幾個服務,并把AMS服務自己保存到localService中供程序內(nèi)部調(diào)用。

AMS的構造方法和start方法中做了AMS服務一些變量的初始化和相關服務的初始化。接著看下一個重要的方法setSystemProcess

ActivityManagerService的setSystemProcess方法

public void setSystemProcess() {
        try {
    //將AMS注冊到ServiceManager中
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    //注冊其他服務到ServiceMananger中
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
    //注冊權限服務到ServiceMananger中
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
    //從PMS中查詢包名為android的application,即framework-res的Application信息
            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS);
        //將application信息配置到開始創(chuàng)建的activityThread中
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
 
            synchronized (this) {
        //創(chuàng)建了一個ProcessRecord對象,該對象中保存著系統(tǒng)ongoing服務的進程信息
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
        然后將系統(tǒng)進程的processRecord對象也添加到mPidsSelfLocked集合中,和普通應用的進程一樣,接收AMS的管理調(diào)度
                    mPidsSelfLocked.put(app.pid, app);
                }
        //更細進程管理的調(diào)度信息
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }

?在setSystemProcess方法中,首先將自己AMS服務注冊到了ServiceManager中,然后又注冊了權限服務等其他的系統(tǒng)服務。通過先前創(chuàng)建的Context,得到PMS服務,檢索framework-res的Application信息,然后將它配置到系統(tǒng)的ActivityThread中。
為了能讓AMS同樣可以管理調(diào)度系統(tǒng)進程,也創(chuàng)建了一個關于系統(tǒng)進程的ProcessRecord對象,ProcessRecord對象保存一個進程的相關信息。然后將它保存到mPidsSelfLocked集合中方便管理。
?但是AMS具體是如何將檢索到的framework-res的application信息,配置到ActivityThread中的,需要繼續(xù)分析ActivityThread的installSystemApplicationInfo方法。
接著看installSystemApplicationInfo方法

public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
        synchronized (this) {
            getSystemContext().installSystemApplicationInfo(info, classLoader);
        }
    }

這個方法中最終調(diào)用上面創(chuàng)建的SystemContext的installSystemApplication方法,那就接著看ConxtextImpl的installSystemApplication方法。

void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
        mPackageInfo.installSystemApplicationInfo(info, classLoader);
    }

它有最終調(diào)用了mPackageInfo的installSystemApplication方法,mPackageInfo就是在創(chuàng)建Context對象的時候傳進來的LoadedApk,里面保存了一個應用程序的基本信息。

void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
        assert info.packageName.equals("android");
        mApplicationInfo = info;
        mClassLoader = classLoader;
    }

?將framework-res.apk的application信息保存到了mApplication變量中。
?我們返回去看下第一次創(chuàng)建LoadedApk的時候,使用了一個參數(shù)的構造方法,該構造方法中mApplication變量是直接new了一個ApplicationInfo的對象,該applicationInfo并沒有指向任何一個應用,為什么開始的時候不直接指定,反而到現(xiàn)在再來重新做一次呢?
?這個是因為創(chuàng)建系統(tǒng)進程的context的時候AMS和PMS都還沒有起來,那時候沒有辦法指定它的application,現(xiàn)在AMS,PMS都起來之后再來賦值就可以了。

?setSystemProcess做了些什么工作呢?顧名思義,主要就是設置系統(tǒng)集成的一些信息,在這里設置了系統(tǒng)進程的Application信息,創(chuàng)建了系統(tǒng)進程的ProcessRecord對象將其保存在進程集合中,方便AMS管理調(diào)度。

ActivityManagerService的installSystemProvider方法

?Android系統(tǒng)中有很多配置信息都需要保存,這些信息是保存在SettingsProvider中,而這個SettingsProvider也是運行在SystemServer進程中的,由于SystemServer進程依賴SettingsProvider,放在一個進程中可以減少進程間通信的效率損失。

下面就來分析下如何將SettingsProvider.apk也加載到SystemServer進程中。

public final void installSystemProviders() {
        List<ProviderInfo> providers;
        synchronized (this) {
            //找到名稱為”System”的進程,就是上一步創(chuàng)建的processRecord對象
            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
            //找到所有和system進程相關的ContentProvider
            providers = generateApplicationProvidersLocked(app);
            if (providers != null) {
                for (int i=providers.size()-1; i>=0; i--) {
                    ProviderInfo pi = (ProviderInfo)providers.get(i);
                    //再次確認進程為system的provider,把不是該進程provider移除
                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                        Slog.w(TAG, "Not installing system proc provider " + pi.name
                                + ": not system .apk");
                        providers.remove(i);
                    }
                }
            }
        }
        if (providers != null) {
            //把provider安裝到系統(tǒng)的ActivityThread中
            mSystemThread.installSystemProviders(providers);
        }
 
        mCoreSettingsObserver = new CoreSettingsObserver(this);
    }

找到名稱為system的進程對象,就是SystemServer進程,然后根據(jù)進程對象去查詢所有有關的ContentProvider,調(diào)用系統(tǒng)進程的主線程ActivityThread安裝所有相關的ContentProvider,

具體是如何查找相關的contentProvider和如何安裝ContentProvider到系統(tǒng)主線程的,接著分析下面兩個方法。

private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
        List<ProviderInfo> providers = null;
        try {
            //調(diào)用PMS根據(jù)進程ID和進程名稱來查詢Provider
            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
                queryContentProviders(app.processName, app.uid,
                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
            providers = slice != null ? slice.getList() : null;
        } catch (RemoteException ex) {
        }
        int userId = app.userId;
        if (providers != null) {
            int N = providers.size();
            for (int i=0; i<N; i++) {
                ProviderInfo cpi =
                    (ProviderInfo)providers.get(i);
               ……
                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
           //從AMS管理的contentProvider列表中查詢對應的provider     
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
                if (cpr == null) {
                    //如果AMS的Provider列表中沒有對應的Provider實例,就根據(jù)查詢的provider信息,創(chuàng)建一個對象保存到隊列中
                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
                    mProviderMap.putProviderByClass(comp, cpr);
                }
               //同時將provider保存到processRecord對象的pubProviders列表中
                app.pubProviders.put(cpi.name, cpr);
                ……
            }
        }
        return providers;
    }

這個方法就是從PMS中查詢和SystemServer進程相關的Provider,也就是SettingsProvder,然后將它保存到AMS的contentProvider列表中,同時也將它保存到系統(tǒng)進程對象ProcessRecord的變量pubProviders列表中,保存到AMS的provider列表中是因為AMS需要管理所有的ContentProvder,保存到進程對象的pubProviders列表中是因為,每個ContentProvider都需要對應到一個進程中去。

接著看如何將SettingsProvider安裝到系統(tǒng)的主進程中去。

private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
         ……
        for (ProviderInfo cpi : providers) {
            //通過installProvider方法把provider封裝成一個ContentProviderHolder對象,有利于進程間傳輸
            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
            if (cph != null) {
                cph.noReleaseNeeded = true;
                results.add(cph);
            }
        }
 
        try {
            //將上面得到的contentProviderHolder對象發(fā)布到AMS服務,getApplicationThread代表本地進程的一個binder對象,binder對象可跨進程傳輸,它在AMS中對應一個ProcessRecord.
            ActivityManagerNative.getDefault().publishContentProviders(
                getApplicationThread(), results);
       ……
    }

該方法將得到的contentProvider對象封裝成了contentProviderHolder對象,其實就是Binder對象,這樣就可以進程間傳輸了,然后跨進程調(diào)用AMS服務注冊Provider。AMS負責管理ContentProvider,只有將ContentProvider注冊到AMS服務其他進程才能訪問。

接著看AMS如何注冊Provider。

public final void publishContentProviders(IApplicationThread caller,
            List<ContentProviderHolder> providers) {
           ……
            //根據(jù)調(diào)用者的進程得到相應的processRecord對象,就是系統(tǒng)進程的ProcessRecord
            final ProcessRecord r = getRecordForAppLocked(caller);
           ……
 
            final int N = providers.size();
            for (int i = 0; i < N; i++) {
                //ActivityThread客戶端傳過來的provider src
                ContentProviderHolder src = providers.get(i);
                //根據(jù)src provider name得到一開始保存的進程中保存的ProciderRecord
                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
               
                if (dst != null) {
                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
                    //按類將它保存在mProviderMap中
                    mProviderMap.putProviderByClass(comp, dst);
                    String names[] = dst.info.authority.split(";");
                    for (int j = 0; j < names.length; j++) {
                        //按authority保存在mProviderMap中
                        mProviderMap.putProviderByName(names[j], dst);
                    }
 
                   ……
                    }

AMS的注冊服務就是根據(jù)參數(shù)傳過來的provider信息,找到原先進程中pubProviders列表中保存的ContentProviderRecord,然后將它分別以類為key保存在mProviderMap中,和以authority為key保存在mProviderMap中。即AMS提供了多種方案來查找一個ContentProvider,一種是通過authority來查找,一種是指明CompomentName來查找。

此刻位置一個SettingsProvider就正式注冊到SystemServer進程中了,所以可以看出installSystemProvider方法的主要工作就是按照普通進程類似的方式,將SettingsProvider注冊到系統(tǒng)進程中,方便系統(tǒng)進程對settings的配置數(shù)據(jù)進行調(diào)用。

ActivityManagerService的systemReady方法

public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            //初始化Doze模式的controller
            mLocalDeviceIdleController
                    = LocalServices.getService(DeviceIdleController.LocalService.class);
 
                
        //重置RecentTasks
            mRecentTasks.clear();
            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
            mTaskPersister.startPersisting();
 
            ……
            //設置systemReady為true
            mSystemReady = true;
        }
 
        ArrayList<ProcessRecord> procsToKill = null;
        //收集那些在AMS之前啟動的進程
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }
       //將那些在AMS之前啟動的進程殺死,有的進程不能再AMS之前啟動
        synchronized(this) {
            if (procsToKill != null) {
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true, false, "system update done");
                }
            }
 
 
        }
 
        //從settingsProvider的設置總初始化部分變量
        retrieveSettings();
        //調(diào)用callback方法,該方法在systemServer代碼中實現(xiàn)
        if (goingCallback != null) goingCallback.run();
 
             
                    //查詢那些persistent為1的application,并啟動他們所在的進程
                    List apps = AppGlobals.getPackageManager().
                        getPersistentApplications(STOCK_PM_FLAGS);
                    if (apps != null) {
                        int N = apps.size();
                        int i;
                        for (i=0; i<N; i++) {
                            ApplicationInfo info
                                = (ApplicationInfo)apps.get(i);
                            if (info != null &&
                                    !info.packageName.equals("android")) {
                                addAppLocked(info, false, null /* ABI override */);
                            }
             
            }
 
            //啟動HomeActivity,也就是launcher程序
            mBooting = true;
            startHomeActivityLocked(mCurrentUserId, "systemReady");
           ……
        }
    }

SystemReady方法也是比較長,大致可以分為四個部分

第一:在systemReady的時候初始化了deviceIdleController等對象
第二:移除并殺死了那些不該在AMS之前啟動的進程
第三:執(zhí)行了參數(shù)傳入的回調(diào)函數(shù)
第四:啟動了Launcer界面
第五:啟動那些persistent配置為1的進程。

再來看些systemReady參數(shù)的回調(diào)函數(shù)做了什么工作.

  try {
                    //ams開始監(jiān)聽native層的crash信息
                    mActivityManagerService.startObservingNativeCrashes();
                } catch (Throwable e) {
                    reportWtf("observing native crashes", e);
                }
                //初始化webVew
                WebViewFactory.prepareWebViewInSystemServer();
 
                try {
                    //啟動systemUI
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }
                try {
                    //調(diào)用其他服務的systemready方法
                    if (networkScoreF != null) networkScoreF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Score Service ready", e);
                }
……

?這個回調(diào)函數(shù)中主要工作就是啟動systemUI并調(diào)用其他服務的systemReady方法,SystemReady函數(shù)完成了系統(tǒng)就緒的必要的工作,啟動了HomeActivity和SystemUI,然后Android系統(tǒng)就全部啟動了。
AMS服務啟動主要分為幾個步驟。

1. 創(chuàng)建了SystemServer進程的運行環(huán)境,包括一個ActivityThread主線程,一個和系統(tǒng)進程相關的Context對象。
2. 調(diào)用AMS的構造方法和start方法,對AMS必要的內(nèi)容進行初始化
3. 將函數(shù)AMS注冊到ServiceManager中,同時對systemServer進程也創(chuàng)建了一個ProcessRecord對象,并設置Context的appliation為framework-res的application對象
4. 將settingsProvider加載到系統(tǒng)進程systemServer中
5. 調(diào)用systemReady方法做一些啟動前的就緒工作,并啟動了HomeActivity和SystemUI

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容