本文基于Android 7.0,记录SystemUI学习过程,如有错误之处 请谅解。
涉及到的代码
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/packages/SystemUI/
SystemUI是系统app,源码位于framework/base/package/SystemUI。
SystemUI启动是从frameworks/base/services/java/com/android/server/SystemServer.java main()开始的。
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
进入到run()中
private void run() {
...
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
所有的系统服务都是在这里启动的,其中在startBootstrapServices()中启动了ActivityManagerService、PowerManagerService、PackageManagerService等一系列核心服务,SystemUI是在startOtherServices()中。
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices(){
...
WindowManagerService wm = null;
...
try {
...
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
...
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
...
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
...
if (!disableSystemUI) {
traceBeginAndSlog("StartStatusBarManagerService");
try {
statusBar = new StatusBarManagerService(context, wm);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
reportWtf("starting StatusBarManagerService", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
mSystemServiceManager.startService(NotificationManagerService.class);
notification = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
...
}
...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
...
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
}
});
}
frameworks/base/services/java/com/android/server/SystemServer.java
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
}
可以看到这里是通过context的startServiceAsUser去启动SystemUIService。该方法的真正实现是在ContextImpl.java
frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
return startServiceCommon(service, user);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
ContextImpl最终会通过binder通信调用到ActivityManagerService的startService方法。
先看一下这里面的参数
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
其中mMainThread是ActivityThread类型对象,即进程里的主线程(UI线程),
在Android应用程序中,每一个进程对应一个ActivityThread实例。mMainThread.getApplicationThread()得到的是ApplicationThread类型对象,ApplicationThread是
ActivityThread的一个对象,ApplicationThread不直接和AMS交互,ApplicationThread对象通过接收一系列指令(scheduleLaunchActivity、scheduleDestroyActivity等)是应用程序进程和AMS真正进行交互的地方。
上述流程都是跑在system_server进程中(DDMS中对应"system_process"进程)。
这里省略了binder通信的过程,直接进入到ActivityManagerService的startService方法
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
//获取调用者信息
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
mServices是ActiveServices类型对象,调用该对象的startServiceLocked方法。
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
...
//先解析要启动的service信息
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false);
...
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
首先通过retrieveServiceLocked去获取service具体信息
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
private ServiceLookupResult retrieveServiceLocked(Intent service,
String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal) {
//每一个启动的service在ams中都有一个对应的ServiceRecord信息
ServiceRecord r = null;
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
+ " type=" + resolvedType + " callingUid=" + callingUid);
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
//ServiceMap是ActiveServices的内部类,其中final ArrayMap mServicesByName保存了已启动的所有service信息
ServiceMap smap = getServiceMap(userId);
final ComponentName comp = service.getComponent();
if (comp != null) {
//查询已启动的service列表中是否有我们要启动的服务,这里SystemuiService还没有启动过,获取到的值为null
r = smap.mServicesByName.get(comp);
}
...
//r == null 为true,会执行如下if
if (r == null) {
try {
// TODO: come back and remove this assumption to triage all services
//开机的时候PackageManagerService会去解析安装每一个apk,并保存相应的信息,从PackageManagerService中获取到service信息
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
resolvedType, ActivityManagerService.STOCK_PM_FLAGS
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
userId);
ServiceInfo sInfo =
rInfo != null ? rInfo.serviceInfo : null;
...
r = smap.mServicesByName.get(name);
if (r == null && createIfNeeded) {
Intent.FilterComparison filter
= new Intent.FilterComparison(service.cloneFilter());
ServiceRestarter res = new ServiceRestarter();
BatteryStatsImpl.Uid.Pkg.Serv ss = null;
BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
ss = stats.getServiceStatsLocked(
sInfo.applicationInfo.uid, sInfo.packageName,
sInfo.name);
}
//创建ServiceRecord,并且保存信息到ServiceMap中
r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
res.setService(r);
smap.mServicesByName.put(name, r);
smap.mServicesByIntent.put(filter, r);
// Make sure this component isn't in the pending list.
//mPendingServices中保存了要启动的service列表
for (int i=mPendingServices.size()-1; i>=0; i--) {
ServiceRecord pr = mPendingServices.get(i);
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
&& pr.name.equals(name)) {
mPendingServices.remove(i);
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
}
if (r != null) {
...
return new ServiceLookupResult(r, null);
}
return null;
}
处理好ServiceRecord之后,回到ActiveServices的startServiceLocked方法继续执行startServiceInnerLocked
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
return r.name;
}
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 {
...
//processName,可以在AndroidManifest.xml通过android:process去指定进程名称,如果不指定默认是应用包名
final String procName = r.processName;
//每一个process在ams都对应一个ProcessRecord
ProcessRecord app;
...
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
//开始创建一个新的进程去启动服务
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//将ServiceRecord加入mPendingServices列表,后面会用到
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
...
return null;
}
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
...
ProcessRecord app;
...
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
...
return (app.pid != 0) ? app : null;
}
startProcessLocked中调用Process.start去创建进程
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
try {
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
...
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
...
} catch (RuntimeException e) {
...
}
}
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
...
//创建looper
Looper.prepareMainLooper();
//创建一个ActivityThread
ActivityThread thread = new ActivityThread();
thread.attach(false);
...
//进入looper消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//非system进程,这里system进程是指system_server,其他为非system进程
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
}
...
});
}
IActivityManager的attachApplication中使用mAppThread参数是ApplicationThread类型的,在new ActivityThread()的时候自动创建。前面所述,该变量是用来真正和ams进行交互的。接下来通过binder通信进入到ams的attachApplication中
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
//首先根据进程pid去ams中找出进程的ProcessRecord
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
...
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
//systemui中不需要启动activity
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
...
return true;
}
调用了ActiveServices的attachApplicationLocked方法
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
//service第一次start走这里
//前面我们将要启动的systemuiservice放入到了mPendingServices中,现在取出来
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i 0) {
ServiceRecord sr;
for (int i=0; i
前面把systemuiservice保存到了mPendingServices中,将其取出来开始真正启动systemuiservice
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
try {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
...
} catch (DeadObjectException e) {
...
} finally {
...
}
...
}
这里我们可以再次看到,ActivityThread是不直接和ams交互的,而是通过其内部类ApplicationThread去交互,即ActivityThread通过ApplicationThread和ams交互。进入到ApplicationThread的scheduleCreateService
frameworks/base/core/java/android/app/ActivityThread.java
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
ApplicationThread简单的发送了一个CREATE_SERVICE的消息到主线程ActivityThread
frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
//启动activity走这里
...
} break;
...
case PAUSE_ACTIVITY: {
//pause activity走这里
...
} break;
...
case RESUME_ACTIVITY:
//resume activity走这里
...
break;
...
case DESTROY_ACTIVITY:
//destroy activity走这里
...
break;
...
case RECEIVER:
//广播走这里
...
break;
case CREATE_SERVICE:
//启动服务走这里
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
//bindservice走这里
break;
...
}
}
frameworks/base/core/java/android/app/ActivityThread.java
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//通过ClassLoader去加载创建要启动的服务对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//创建service运行环境
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//最后直接调用service对象的onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
handleCreateService中创建了服务对象,并且调用该服务的onCreate方法,进入到SystemUiService的onCreate方法
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
这样SystemUI就被启动起来了。