深入分析AMS启动流程

移动开发 Android
AMS(ActivityManagerService)Android的核心服务之一,对于framework各个核心服务,如果不是专门去做framework开发,先了解其基本的流程机制,再慢慢深究;今天我们就来学习下AMS.

[[432146]]

前言

AMS(ActivityManagerService)Android的核心服务之一,对于framework各个核心服务,如果不是专门去做framework开发,先了解其基本的流程机制,再慢慢深究;

今天我们就来学习下AMS

一、AMS功能概述

1、AMS介绍

  • AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要;
  • 组件状态管理:包括四大组件的开启,关闭等一系列操作,如startActivity,startActivityAndWait,activityPaused,startService,stopService,removeContentProvider等;
  • 组件状态查询:查询组件当前运行等情况。如getCallingActivity,getService等;
  • Task相关:包括removeTask,removeSubTask,moveTaskBackwards,moveTaskToFront等;
  • AMS是通过ActivityStack及其他数据结构来记录,管理系统中的Activity及其他组件状态的,并提供查询功能的一个系统服务;

2、AMS中重要的数据结构

ActivityRecord:记录了Activity的所有信息,因此它用来描述一个activity。它是在activity启动时被创建的,具体是在ActivityStarter的startActivity()中被创建的。它存储的信息主要包括以下内容:

  • service:AMS的引用
  • info:ActivityInfo,Activity中代码和AndroidManifest设置的节点信息,如launchMode
  • launcherFromPackage:启动activity的包名
  • taskAffinity:activity希望归属的栈
  • task:TaskRecord,Activity所在的TaskRecord
  • app:ProcessRecord,ActivityRecord所在的应用程序进程
  • state:ActivityState,当前activity的状态
  • icon:Activity的图标资源和标致符
  • theme:Activity的主题资源标识符

TaskRecord:用来描述一个Activity任务栈

  • taskId:任务栈的唯一标识符
  • affinity:任务栈的倾向性
  • Intent:启动这个activity的intent
  • mActivites:ArrayList,按照历史顺序排列的Activity记录
  • mStack:ActivityStack,当前归属的ActivityStack
  • mService:AMS的引用

ActivityStack:用来管理系统所有的Activity,内部维护了Activity的所有状态,特殊状态的Activity以及和Activity相关的列表等数据;

 

 

二、AMS服务的启动流程详解

1、startBootstrapServices

  1. private void startBootstrapServices() { 
  2.         // Activity manager runs the show. 
  3.      mActivityManagerService = mSystemServiceManager.startService( 
  4.                 ActivityManagerService.Lifecycle.class).getService(); 
  5.      mActivityManagerService.setSystemProcess(); 
  6. …… 
  7.      mActivityManagerService.installSystemProviders(); 
  8. …… 
  9.      mActivityManagerService.systemReady(new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 Slog.i(TAG, "Making services ready"); 
  13.                 mSystemServiceManager.startBootPhase( 
  14.                         SystemService.PHASE_ACTIVITY_MANAGER_READY); 
  15.                 try { 
  16.                     mActivityManagerService.startObservingNativeCrashes(); 
  17.                 } catch (Throwable e) { 
  18.                     reportWtf("observing native crashes", e); 
  19.                 } 

SystemServer中关于AMS启动时的几个关键方法,主要分为4个步骤

  • 创建AMS对象,并启动服务
  • 将AMS所在的系统进程,添加到进程管理中去
  • 为系统进程安装ContentProvider对象
  • 在systemReady方法中做善后操作
  • 一个一个的来看先这些方法的作用,这些方法就是AMS的启动和初始化过程;

2、ActivityManagerService

启动ActivityManagerService的方法

mActivityManagerService = mSystemServiceManager.startService(

ActivityManagerService.Lifecycle.class).getService();

AMS服务同样是通过SystemServiceManager来启动的,那我们首先来看ActivityManagerService.Lifecycle的构造方法,然后在来看它的Start函数;

Lifecycle的构造方法中很简单就是构造一个AMS的对象

mService = new ActivityManagerService(context);

创建AMS对象的时候需要传递一个Context作为参数,那这个mSystemContext是就是上面创建的系统Context;

接着看AMS的构造方法;

  1. public ActivityManagerService(Context systemContext) { 
  2. //系统的context         
  3. mContext = systemContext; 
  4.     //获得系统的ActivityThread 
  5.         mSystemThread = ActivityThread.currentActivityThread(); 
  6.     //创建一个HandlerThread用来处理AMS接收的命令 
  7.         mHandlerThread = new ServiceThread(TAG, 
  8.                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 
  9.         mHandlerThread.start(); 
  10.         mHandler = new MainHandler(mHandlerThread.getLooper()); 
  11.         mUiHandler = new UiHandler(); 
  12.     //初始化广播的队列 
  13.         mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 
  14.                 "foreground", BROADCAST_FG_TIMEOUT, false); 
  15.         mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 
  16.                 "background", BROADCAST_BG_TIMEOUT, true); 
  17.         mBroadcastQueues[0] = mFgBroadcastQueue; 
  18.         mBroadcastQueues[1] = mBgBroadcastQueue; 
  19.     //初始化Service相关的容器 
  20.         mServices = new ActiveServices(this); 
  21.     //初始化Provider相关的Map,里面保存了注册的ContentProvider 
  22.         mProviderMap = new ProviderMap(this); 
  23.         //初始化并创建data/system/目录 
  24.         File dataDir = Environment.getDataDirectory(); 
  25.         File systemDir = new File(dataDir, "system"); 
  26.         systemDir.mkdirs(); 
  27.     //初始化电量统计服务相关的信息 
  28.         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 
  29.         mBatteryStatsService.getActiveStatistics().readLocked(); 
  30.         mBatteryStatsService.scheduleWriteToDisk(); 
  31.         mOnBattery = DEBUG_POWER ? true 
  32.                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 
  33.         mBatteryStatsService.getActiveStatistics().setCallback(this); 
  34.     //初始化系统统计服务,用于统计系统的运行信息 
  35.         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 
  36.         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 
  37.         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 
  38.         //创建系统的第一个user,userID为0,该用户具有管理员权限 
  39.         mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true)); 
  40.         mUserLru.add(UserHandle.USER_OWNER); 
  41.         updateStartedUserArrayLocked(); 
  42.     //获取opengle的版本 
  43.         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version"
  44.             ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 
  45.         //初始化字体语言等配置信息 
  46.         mConfiguration.setToDefaults(); 
  47.         mConfiguration.setLocale(Locale.getDefault()); 
  48.      ……; 
  49.         mRecentTasks = new RecentTasks(this); 
  50.     //初始化StackSupervisor,该类是Activity启动和调度的核心类 
  51.         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks); 
  52.         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks); 
  • AMS的构造方法主要是在做一些初始化的先关操作;
  • 保存了自己的运行环境的Context和ActivityThread;
  • AMS负责调度四大组件,所以会初始化broadcast,service和contentProvider相关的变量,接着初始化了电量统计服务,创建了系统的第一个用户,初始化了基本的配置信息,还创建了Activity调度的核心类,因为Activity调度比较复杂,Activity相关的信息初始化会在ActivityStackSupervisor中;

3、start

AMS的start方法。

  1. private void start() { 
  2.      mProcessCpuThread.start(); 
  3.      mBatteryStatsService.publish(mContext); 
  4.      LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 
  5.  } 
  • AMS的start方法很简单,只是启动了几个服务,并把AMS服务自己保存到localService中供程序内部调用;
  • AMS的构造方法和start方法中做了AMS服务一些变量的初始化和相关服务的初始化。接着看下一个重要的方法setSystemProcess;

4、setSystemProcess

ActivityManagerService的setSystemProcess方法

  1. public void setSystemProcess() { 
  2.         try { 
  3.     //将AMS注册到ServiceManager中 
  4.             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 
  5.     //注册其他服务到ServiceMananger中 
  6.             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 
  7.             ServiceManager.addService("meminfo", new MemBinder(this)); 
  8.             ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 
  9.             ServiceManager.addService("dbinfo", new DbBinder(this)); 
  10.             if (MONITOR_CPU_USAGE) { 
  11.                 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 
  12.             } 
  13.     //注册权限服务到ServiceMananger中 
  14.             ServiceManager.addService("permission", new PermissionController(this)); 
  15.             ServiceManager.addService("processinfo", new ProcessInfoService(this)); 
  16.     //从PMS中查询包名为android的application,即framework-res的Application信息 
  17.             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 
  18.                     "android", STOCK_PM_FLAGS); 
  19.         //将application信息配置到开始创建的activityThread中 
  20.             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 
  21.             synchronized (this) { 
  22.         //创建了一个ProcessRecord对象,该对象中保存着系统ongoing服务的进程信息 
  23.                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 
  24.                 app.persistent = true
  25.                 app.pid = MY_PID; 
  26.                 app.maxAdj = ProcessList.SYSTEM_ADJ; 
  27.                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 
  28.                 synchronized (mPidsSelfLocked) { 
  29.         然后将系统进程的processRecord对象也添加到mPidsSelfLocked集合中,和普通应用的进程一样,接收AMS的管理调度 
  30.                     mPidsSelfLocked.put(app.pid, app); 
  31.                 } 
  32.         //更细进程管理的调度信息 
  33.                 updateLruProcessLocked(app, falsenull); 
  34.                 updateOomAdjLocked(); 
  35.             } 
  • setSystemProcess方法中,首先将自己AMS服务注册到了ServiceManager中,然后又注册了权限服务等其他的系统服务;
  • 通过先前创建的Context,得到PMS服务,检索framework-res的Application信息,然后将它配置到系统的ActivityThread中;
  • 为了能让AMS同样可以管理调度系统进程,也创建了一个关于系统进程的ProcessRecord对象,ProcessRecord对象保存一个进程的相关信息;
  • 然后将它保存到mPidsSelfLocked集合中方便管理;
  • AMS具体是如何将检索到的framework-res的application信息,配置到ActivityThread中的,需要继续分析ActivityThread的installSystemApplicationInfo方法;

接着看installSystemApplicationInfo方法

  1. public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 
  2.         synchronized (this) { 
  3.             getSystemContext().installSystemApplicationInfo(info, classLoader); 
  4.         } 
  5.     } 

这个方法中最终调用上面创建的SystemContext的installSystemApplication方法,那就接着看ConxtextImpl的installSystemApplication方法。

  1. void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 
  2.         mPackageInfo.installSystemApplicationInfo(info, classLoader); 
  3.     } 
  • 它有最终调用了mPackageInfo的installSystemApplication方法,mPackageInfo就是在创建Context对象的时候传进来的LoadedApk,里面保存了一个应用程序的基本信息;
  • setSystemProcess主要就是设置系统集成的一些信息,在这里设置了系统进程的Application信息,创建了系统进程的ProcessRecord对象将其保存在进程集合中,方便AMS管理调度;

5、installSystemProvider

  • ActivityManagerService的installSystemProvider方法;
  • Android系统中有很多配置信息都需要保存,这些信息是保存在SettingsProvider中,而这个SettingsProvider也是运行在SystemServer进程中的,由于SystemServer进程依赖SettingsProvider,放在一个进程中可以减少进程间通信的效率损失;
  • 下面就来分析下如何将SettingsProvider.apk也加载到SystemServer进程中;

  1. public final void installSystemProviders() { 
  2.         List<ProviderInfo> providers; 
  3.         synchronized (this) { 
  4.             //找到名称为”System”的进程,就是上一步创建的processRecord对象 
  5.             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 
  6.             //找到所有和system进程相关的ContentProvider 
  7.             providers = generateApplicationProvidersLocked(app); 
  8.             if (providers != null) { 
  9.                 for (int i=providers.size()-1; i>=0; i--) { 
  10.                     ProviderInfo pi = (ProviderInfo)providers.get(i); 
  11.                     //再次确认进程为system的provider,把不是该进程provider移除 
  12.                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 
  13.                         Slog.w(TAG, "Not installing system proc provider " + pi.name 
  14.                                 + ": not system .apk"); 
  15.                         providers.remove(i); 
  16.                     } 
  17.                 } 
  18.             } 
  19.         } 
  20.         if (providers != null) { 
  21.             //把provider安装到系统的ActivityThread中 
  22.             mSystemThread.installSystemProviders(providers); 
  23.         } 
  24.         mCoreSettingsObserver = new CoreSettingsObserver(this); 
  25.     } 

找到名称为system的进程对象,就是SystemServer进程,然后根据进程对象去查询所有有关的ContentProvider,调用系统进程的主线程ActivityThread安装所有相关的ContentProvider,具体是如何查找相关的contentProvider和如何安装ContentProvider到系统主线程的,接着分析下面两个方法;

  1. private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 
  2.         List<ProviderInfo> providers = null
  3.         try { 
  4.             //调用PMS根据进程ID和进程名称来查询Provider 
  5.             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager(). 
  6.                 queryContentProviders(app.processName, app.uid, 
  7.                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 
  8.             providers = slice != null ? slice.getList() : null
  9.         } catch (RemoteException ex) { 
  10.         } 
  11.         int userId = app.userId; 
  12.         if (providers != null) { 
  13.             int N = providers.size(); 
  14.             for (int i=0; i<N; i++) { 
  15.                 ProviderInfo cpi = 
  16.                     (ProviderInfo)providers.get(i); 
  17.                …… 
  18.                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 
  19.            //从AMS管理的contentProvider列表中查询对应的provider      
  20. ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 
  21.                 if (cpr == null) { 
  22.                     //如果AMS的Provider列表中没有对应的Provider实例,就根据查询的provider信息,创建一个对象保存到队列中 
  23.                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 
  24.                     mProviderMap.putProviderByClass(comp, cpr); 
  25.                 } 
  26.                //同时将provider保存到processRecord对象的pubProviders列表中 
  27.                 app.pubProviders.put(cpi.name, cpr); 
  28.                 …… 
  29.             } 
  30.         } 
  31.         return providers; 
  32.     } 

  • 这个方法就是从PMS中查询和SystemServer进程相关的Provider,也就是SettingsProvder,然后将它保存到AMS的contentProvider列表中;
  • 同时也将它保存到系统进程对象ProcessRecord的变量pubProviders列表中,保存到AMS的provider列表中是因为AMS需要管理所有的ContentProvder;
  • 保存到进程对象的pubProviders列表中是因为,每个ContentProvider都需要对应到一个进程中去;
  • 接着看如何将SettingsProvider安装到系统的主进程中去;

  1. private void installContentProviders( 
  2.             Context context, List<ProviderInfo> providers) { 
  3.          …… 
  4.         for (ProviderInfo cpi : providers) { 
  5.             //通过installProvider方法把provider封装成一个ContentProviderHolder对象,有利于进程间传输 
  6.             IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 
  7.                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 
  8.             if (cph != null) { 
  9.                 cph.noReleaseNeeded = true
  10.                 results.add(cph); 
  11.             } 
  12.         } 
  13.         try { 
  14.             //将上面得到的contentProviderHolder对象发布到AMS服务,getApplicationThread代表本地进程的一个binder对象,binder对象可跨进程传输,它在AMS中对应一个ProcessRecord. 
  15.             ActivityManagerNative.getDefault().publishContentProviders( 
  16.                 getApplicationThread(), results); 
  17.        …… 
  18.     } 
  • 该方法将得到的contentProvider对象封装成了contentProviderHolder对象,其实就是Binder对象,这样就可以进程间传输了,然后跨进程调用AMS服务注册Provider;
  • AMS负责管理ContentProvider,只有将ContentProvider注册到AMS服务其他进程才能访问;
  • 接着看AMS如何注册Provider;

6、publishContentProviders

  1. public final void publishContentProviders(IApplicationThread caller, 
  2.             List<ContentProviderHolder> providers) { 
  3.            …… 
  4.             //根据调用者的进程得到相应的processRecord对象,就是系统进程的ProcessRecord 
  5.             final ProcessRecord r = getRecordForAppLocked(caller); 
  6.            …… 
  7.             final int N = providers.size(); 
  8.             for (int i = 0; i < N; i++) { 
  9.                 //ActivityThread客户端传过来的provider src 
  10.                 ContentProviderHolder src = providers.get(i); 
  11.                 //根据src provider name得到一开始保存的进程中保存的ProciderRecord 
  12.                 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 
  13.                 if (dst != null) { 
  14.                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 
  15.                     //按类将它保存在mProviderMap中 
  16.                     mProviderMap.putProviderByClass(comp, dst); 
  17.                     String names[] = dst.info.authority.split(";"); 
  18.                     for (int j = 0; j < names.length; j++) { 
  19.                         //按authority保存在mProviderMap中 
  20.                         mProviderMap.putProviderByName(names[j], dst); 
  21.                     } 
  22.                    …… 
  23.                     } 
  • AMS的注册服务就是根据参数传过来的provider信息,找到原先进程中pubProviders列表中保存的ContentProviderRecord,然后将它分别以类为key保存在mProviderMap中,和以authority为key保存在mProviderMap中;
  • 即AMS提供了多种方案来查找一个ContentProvider,一种是通过authority来查找,一种是指明CompomentName来查找;
  • 此刻位置一个SettingsProvider就正式注册到SystemServer进程中了,所以可以看出installSystemProvider方法的主要工作就是按照普通进程类似的方式,将SettingsProvider注册到系统进程中,方便系统进程对settings的配置数据进行调用;

7、systemReady

ActivityManagerService的systemReady方法

  1. public void systemReady(final Runnable goingCallback) { 
  2.         synchronized(this) { 
  3.             //初始化Doze模式的controller 
  4.             mLocalDeviceIdleController 
  5.                     = LocalServices.getService(DeviceIdleController.LocalService.class); 
  6.         //重置RecentTasks 
  7.             mRecentTasks.clear(); 
  8.             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked()); 
  9.             mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 
  10.             mTaskPersister.startPersisting(); 
  11.             …… 
  12.             //设置systemReady为true 
  13.             mSystemReady = true
  14.         } 
  15.         ArrayList<ProcessRecord> procsToKill = null
  16.         //收集那些在AMS之前启动的进程 
  17.         synchronized(mPidsSelfLocked) { 
  18.             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 
  19.                 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 
  20.                 if (!isAllowedWhileBooting(proc.info)){ 
  21.                     if (procsToKill == null) { 
  22.                         procsToKill = new ArrayList<ProcessRecord>(); 
  23.                     } 
  24.                     procsToKill.add(proc); 
  25.                 } 
  26.             } 
  27.         } 
  28.        //将那些在AMS之前启动的进程杀死,有的进程不能再AMS之前启动 
  29.         synchronized(this) { 
  30.             if (procsToKill != null) { 
  31.                 for (int i=procsToKill.size()-1; i>=0; i--) { 
  32.                     ProcessRecord proc = procsToKill.get(i); 
  33.                     Slog.i(TAG, "Removing system update proc: " + proc); 
  34.                     removeProcessLocked(proc, truefalse"system update done"); 
  35.                 } 
  36.             } 
  37.         } 
  38.         //从settingsProvider的设置总初始化部分变量 
  39.         retrieveSettings(); 
  40.         //调用callback方法,该方法在systemServer代码中实现 
  41.         if (goingCallback != null) goingCallback.run(); 
  42.                     //查询那些persistent为1的application,并启动他们所在的进程 
  43.                     List apps = AppGlobals.getPackageManager(). 
  44.                         getPersistentApplications(STOCK_PM_FLAGS); 
  45.                     if (apps != null) { 
  46.                         int N = apps.size(); 
  47.                         int i; 
  48.                         for (i=0; i<N; i++) { 
  49.                             ApplicationInfo info 
  50.                                 = (ApplicationInfo)apps.get(i); 
  51.                             if (info != null && 
  52.                                     !info.packageName.equals("android")) { 
  53.                                 addAppLocked(info, falsenull /* ABI override */); 
  54.                             } 
  55.             } 
  56.             //启动HomeActivity,也就是launcher程序 
  57.             mBooting = true
  58.             startHomeActivityLocked(mCurrentUserId, "systemReady"); 
  59.            …… 
  60.         } 
  61.     } 

SystemReady方法也是比较长,大致可以分为:

  • 第一:在systemReady的时候初始化了deviceIdleController等对象
  • 第二:移除并杀死了那些不该在AMS之前启动的进程
  • 第三:执行了参数传入的回调函数
  • 第四:启动了Launcer界面
  • 第五:启动那些persistent配置为1的进程;
  • 再来看些systemReady参数的回调函数做了什么工作.
  1. try { 
  2.                     //ams开始监听native层的crash信息 
  3.                     mActivityManagerService.startObservingNativeCrashes(); 
  4.                 } catch (Throwable e) { 
  5.                     reportWtf("observing native crashes", e); 
  6.                 } 
  7.                 //初始化webVew 
  8.                 WebViewFactory.prepareWebViewInSystemServer(); 
  9.                 try { 
  10.                     //启动systemUI 
  11.                     startSystemUi(context); 
  12.                 } catch (Throwable e) { 
  13.                     reportWtf("starting System UI", e); 

  14.                 } 
  15.                 try { 
  16.                     //调用其他服务的systemready方法 
  17.                     if (networkScoreF != null) networkScoreF.systemReady(); 
  18.                 } catch (Throwable e) { 
  19.                     reportWtf("making Network Score Service ready", e); 
  20.                 } 

这个回调函数中主要工作就是启动systemUI并调用其他服务的systemReady方法,SystemReady函数完成了系统就绪的必要的工作,启动了HomeActivity和SystemUI,然后Android系统就全部启动了;

总结

AMS服务启动主要分为几个步骤:

  • 调用AMS的构造方法和start方法,对AMS必要的内容进行初始化;
  • 将函数AMS注册到ServiceManager中,同时对systemServer进程也创建了一个ProcessRecord对象,并设置Context的appliation为framework-res的application对象;
  • 将settingsProvider加载到系统进程systemServer中;
  • 调用systemReady方法做一些启动前的就绪工作,并启动了HomeActivity和SystemUI;

本文转载自微信公众号「Android开发编程」

 

责任编辑:姜华 来源: Android开发编程
相关推荐

2010-09-07 14:21:22

PPPoE协议

2022-04-12 08:30:45

TomcatWeb 应用Servlet

2011-03-23 11:01:55

LAMP 架构

2010-03-08 14:53:48

Linux分区

2023-02-01 08:13:30

Redis内存碎片

2011-09-01 13:51:52

JavaScript

2009-12-14 14:50:46

Ruby传参数

2009-06-10 18:12:38

Equinox动态化OSGi动态化

2022-08-30 07:00:18

执行引擎Hotspot虚拟机

2009-12-16 16:39:01

Visual Stud

2018-10-25 15:24:10

ThreadLocal内存泄漏Java

2021-04-13 12:55:06

SpringMVC解析器接口

2015-08-03 09:54:26

Java线程Java

2018-12-18 10:11:37

软件复杂度软件系统软件开发

2011-09-13 09:08:22

架构

2020-12-07 06:23:48

Java内存

2023-08-07 07:44:44

2013-11-14 17:02:41

Android多窗口

2009-07-03 11:14:57

2011-06-28 14:11:33

JavaScript
点赞
收藏

51CTO技术栈公众号