前文回顾:
根据上文分析,AMS和PMS等核心服务已通过startBootstrapServices和startCoreServices方法完成初始化。那么WMS作为另一个关键服务,其创建时机是什么?此外,系统服务初始化后又是如何通过context提供给应用使用的?本文将逐步深入探讨这些问题。
首先来看看之前startBootstrapManager方法中创建AMS的代码:
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
.....
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
// installer守护线程不进行分析了
mActivityManagerService.setInstaller(installer);
.....
mActivityManagerService.setSystemProcess();
那我们来看看AMS中的代码中这几个方法的作用:setSystemServiceManager是一个简单的set方法就不进行分析了。主要是核心方法setSystemProcess,在这个方法中,调用ServiceManager的addService将核心系统服务AMS注册到ServiceManager中。这里我们看到了熟悉的Context.ACTIVITY_SERVICE这个常量。
// 简单的set方法
public void setSystemServiceManager(SystemServiceManager mgr) {
mSystemServiceManager = mgr;
}
// 核心方法
public void setSystemProcess() {
try {
// 1. 注册核心系统服务到 ServiceManager
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
// 2. 根据条件注册 CPU 使用情况监视服务
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
// 3. 注册权限和进程信息服务
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
// 4. 获取 Android 系统包的应用信息
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
// 5. 为系统线程安装系统应用信息
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
// 6. 创建并配置系统进程记录
synchronized (this) {
// 创建新的进程记录
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
// 标记为持久化进程(不会被轻易杀死)
app.persistent = true;
// 设置进程 ID 为当前进程 ID
app.pid = MY_PID;
// 设置最大调整值(adj)为系统级别
app.maxAdj = ProcessList.SYSTEM_ADJ;
// 激活进程记录,关联应用线程和进程统计信息
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
// 7. 将进程记录添加到进程映射表中
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
// 8. 更新 LRU(最近最少使用)进程列表
updateLruProcessLocked(app, false, null);
// 9. 更新进程的 OOM(内存不足)调整值
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
// 10. 异常处理:如果找不到 Android 系统包则抛出运行时异常
throw new RuntimeException(
"Unable to find android system package", e);
}
}
继续分析ServiceManager的addService方法,主要是调用getIServiceManager中的addService方法,再来看看getIServiceManager方法,主要是返回一个ServiceManagerProxy内部类。然后调用这个内部类的addService()方法,在这个方法中,构建了一个Parcel数据包对象然后调用mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);方法将数据和操作发送给了binder,然后将服务添加到system_server中。其实当每一个系统服务创建以后,都会调用ServiceManager的addService方法。
/**
* 将名为 @a name 的新服务 @a service 添加到服务管理器
*
* @param name 新服务的名称
* @param service 服务对象
* @param allowIsolated 设置为true以允许隔离的沙盒进程访问此服务
*/
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
// 获取服务管理器接口并调用其addService方法
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
// 处理远程调用异常,记录错误日志
Log.e(TAG, "error in addService", e);
}
}
/**
* 获取服务管理器接口的单例实例
* 使用双重检查锁定模式确保线程安全
*
* @return IServiceManager 服务管理器接口实例
*/
private static IServiceManager getIServiceManager() {
// 第一次检查:如果实例已存在,直接返回
if (sServiceManager != null) {
return sServiceManager;
}
// 同步块,确保线程安全
synchronized (ServiceManager.class) {
// 第二次检查:防止多个线程同时进入同步块时重复创建实例
if (sServiceManager == null) {
// 获取Binder上下文对象(通常是Binder代理对象)
IBinder binder = BinderInternal.getContextObject();
// 允许阻塞调用
IBinder blockingBinder = Binder.allowBlocking(binder);
// 将Binder对象转换为IServiceManager接口
sServiceManager = ServiceManagerNative.asInterface(blockingBinder);
}
}
return sServiceManager;
}
ServiceManagerNative.java中的asInterface
/**
* 将Binder对象转换为服务管理器接口,必要时生成代理
*
* @param obj 要转换的Binder对象
* @return IServiceManager 服务管理器接口实例
*/
static public IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// 首先查询本地接口(检查是否在同一进程)
IServiceManager in = (IServiceManager) obj.queryLocalInterface(descriptor);
if (in != null) {
// 如果是本地接口(在同一进程),直接返回
return in;
}
// 如果是远程接口(在不同进程),创建代理对象处理跨进程通信
return new ServiceManagerProxy(obj);
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
// 核心方法
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
那我们再来看看另一个核心系统服务WMS是什么时候启动的。查找之后发现WMS在startOtherServices方法中,不过可以看到,WMS是直接调用了自身的静态main方法,然后同AMS一样调用ServiceManager.addService方法的将服务添加到注册表中。
private void startOtherServices() {
final Context context = mSystemContext;
VibratorService vibrator = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
NetworkScoreService networkScore = null;
NsdService serviceDiscovery= null;
WindowManagerService wm = null;
............
traceBeginAndSlog("StartWindowManagerService");
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
............
}
综上,启动SystemService有两种方式:
1.调用SystemServiceManager的startService方法调用目标服务的onstart生命周期方法。
2.直接创建目标服务的对象或者直接调用目标对象的main函数。
继续分析startOtherServices方法。根据注释可以看出来在所有系统服务启动以后,会调用各个服务的systemReady方法。
(代码太长了只展示部分)
// It is now time to start up the app processes...
// 启动应用程序
traceBeginAndSlog("MakeVibratorServiceReady");
try {
vibrator.systemReady();
} catch (Throwable e) {
reportWtf("making Vibrator Service ready", e);
}
traceEnd();
traceBeginAndSlog("MakeLockSettingsServiceReady");
if (lockSettings != null) {
try {
lockSettings.systemReady();
} catch (Throwable e) {
reportWtf("making Lock Settings Service ready", e);
}
}
traceEnd();
// Needed by DevicePolicyManager for initialization
traceBeginAndSlog("StartBootPhaseLockSettingsReady");
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
traceEnd();
traceBeginAndSlog("StartBootPhaseSystemServicesReady");
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
traceEnd();
traceBeginAndSlog("MakeWindowManagerServiceReady");
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
traceEnd();
if (safeMode) {
mActivityManagerService.showSafeModeOverlay();
}
// Update the configuration for this context by hand, because we're going
// to start using it before the config change done in wm.systemReady() will
// propagate to it.
final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
DisplayMetrics metrics = new DisplayMetrics();
WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
w.getDefaultDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);
// The system context's theme may be configuration-dependent.
final Theme systemTheme = context.getTheme();
if (systemTheme.getChangingConfigurations() != 0) {
systemTheme.rebase();
}
traceBeginAndSlog("MakePowerManagerServiceReady");
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
traceEnd();
traceBeginAndSlog("MakePackageManagerServiceReady");
try {
mPackageManagerService.systemReady();
} catch (Throwable e) {
reportWtf("making Package Manager Service ready", e);
}
traceEnd();
下面以AMS的systemReady方法为例进行分析。当系统准备就绪以后会进行一系列初始化操作,并通知其它关联方系统已就绪,然后找到HomeActivity并启动,然后发送广播。AMS的systemReady方法的源码分析部分将在后续笔记中详细展开。
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
// 开始记录"ActivityManagerReady"阶段的性能轨迹,用于分析启动时间
traceLog.traceBegin("PhaseActivityManagerReady");
synchronized(this) {
// 检查系统是否已经准备就绪,避免重复初始化
if (mSystemReady) {
// 如果已经就绪,并且传入了回调,则直接执行回调并返回
if (goingCallback != null) {
goingCallback.run();
}
return;
}
// 获取设备空闲控制器服务,用于管理设备空闲状态(如Doze模式)
mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
// 初始化辅助功能工具类(用于实现Google Now on Tap等功能)
mAssistUtils = new AssistUtils(mContext);
// 通知VR控制器系统已就绪
mVrController.onSystemReady();
// 确保获取当前用户配置文件信息,因为安全检查需要它
mUserController.onSystemReady();
// 通知最近任务列表系统就绪
mRecentTasks.onSystemReadyLocked();
// 通知AppOpsService(应用操作权限服务)系统就绪
mAppOpsService.systemReady();
// 标记ActivityManagerService本身已准备就绪
mSystemReady = true;
}
// 尝试获取设备的真实序列号(用于标识设备)
try {
sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
.getSerial();
} catch (RemoteException e) {} // 忽略获取序列号时的远程异常
// 创建一个列表,用于存储在系统更新期间不允许运行、需要杀死的进程
ArrayList<ProcessRecord> procsToKill = null;
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); // 将不允许的进程添加到待杀死列表
}
}
}
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");
}
}
// 现在我们已经清理了所有更新进程,准备启动真正的应用进程
// 并确保不会再有进程冲突
mProcessesReady = true; // 标记进程系统已准备就绪
}
// 记录系统就绪的日志
Slog.i(TAG, "System now ready");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());
synchronized(this) {
// 确保没有预就绪的进程残留(在工厂测试模式下)
// 处理低级工厂测试模式
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
ResolveInfo ri = mContext.getPackageManager()
.resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
CharSequence errorMsg = null;
if (ri != null) {
ActivityInfo ai = ri.activityInfo;
ApplicationInfo app = ai.applicationInfo;
// 检查工厂测试Activity是否是系统应用
if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// 设置顶部动作为工厂测试
mTopAction = Intent.ACTION_FACTORY_TEST;
mTopData = null;
mTopComponent = new ComponentName(app.packageName, ai.name);
} else {
// 非系统应用,获取错误消息
errorMsg = mContext.getResources().getText(
com.android.internal.R.string.factorytest_not_system);
}
} else {
// 没有找到工厂测试Activity,获取错误消息
errorMsg = mContext.getResources().getText(
com.android.internal.R.string.factorytest_no_action);
}
if (errorMsg != null) {
// 清除顶部组件设置并发送错误消息到UI线程
mTopAction = null;
mTopData = null;
mTopComponent = null;
Message msg = Message.obtain();
msg.what = SHOW_FACTORY_ERROR_UI_MSG;
msg.getData().putCharSequence("msg", errorMsg);
mUiHandler.sendMessage(msg);
}
}
}
// 检索系统设置
retrieveSettings();
final int currentUserId;
synchronized (this) {
// 获取当前用户ID
currentUserId = mUserController.getCurrentUserIdLocked();
// 读取已授权的URI权限
readGrantedUriPermissionsLocked();
}
// 执行传入的回调函数(通常用于通知SystemServer AMS已准备就绪)
if (goingCallback != null) goingCallback.run();
// 开始记录"启动应用"阶段的性能轨迹
traceLog.traceBegin("ActivityManagerStartApps");
// 向电池统计服务记录用户开始运行和切换到前台的事件
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
Integer.toString(currentUserId), currentUserId);
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
Integer.toString(currentUserId), currentUserId);
// 通知系统服务管理器用户已启动
mSystemServiceManager.startUser(currentUserId);
synchronized (this) {
// 只启动支持加密的持久化应用(直接启动感知应用)
// 当用户解锁后,我们会回来启动非感知应用
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
// 启动初始Activity(Launcher)
mBooting = true; // 标记系统正在启动中
// 为系统用户启用Home Activity,确保系统总能启动
// 如果系统用户未完成设置,我们不这样做,因为设置向导应该处理Home Activity
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
// 启动Home Activity(Launcher) - 这是用户看到的第一个界面
startHomeActivityLocked(currentUserId, "systemReady");
// 检查系统UID是否存在不一致
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
+ " data partition or your device will be unstable.");
mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
}
} catch (RemoteException e) {
}
// 检查构建指纹是否一致
if (!Build.isBuildConsistent()) {
Slog.e(TAG, "Build fingerprint is not consistent, warning user");
mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
}
// 清除调用身份以便以系统权限执行操作
long ident = Binder.clearCallingIdentity();
try {
// 广播用户已启动 intent
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, currentUserId);
// 广播用户正在启动 intent
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
} catch (Throwable t) {
Slog.wtf(TAG, "Failed sending first user broadcasts", t);
} finally {
// 恢复调用身份
Binder.restoreCallingIdentity(ident);
}
// 恢复焦点栈的顶部Activity
mStackSupervisor.resumeFocusedStackTopActivityLocked();
// 发送用户切换广播
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
// 结束性能轨迹记录
traceLog.traceEnd(); // ActivityManagerStartApps
traceLog.traceEnd(); // PhaseActivityManagerReady
}
}
总结,当ZygoteInit调用handleSystemServerProcess返回的runnable对象的run方法以后会找到SystemServer.java的静态main函数,在这个main方法中又会去调用startService、addService、systemReady等方法来告知系统服务已经成功启动。