在Activity中使用startService启动Service时,会调用ContextWrapper的startService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/content/ContextWrapper.java
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
这个方法的mBase就是一个ContextImpl类型的对象。所以这里调用了ContextImpl类的startService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
//注意传入的第二个参数是 false ,表示启动的服务不是前台服务
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
// Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//关键代码
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
// ...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
这个方法内部通过先调用validateServiceIntent方法进行Intent检查,Android 5.0后强制要求Service必须通过显式Intent启动5,否则会直接抛出异常,接着调用 ActivityManager.getService()获取到了ActivityManagerService(后面简称AMS)在app进程的代理对象,并调用了这个代理对象的startService方法,下面看看AMS中的startService方法的具体实现:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// ...
synchronized(this) {
// ...
ComponentName res;
try {
// 关键代码
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
这个方法内部通过mServices.startServiceLocked方法,mServices是ActiveServices类型的,所以调用了ActiveServices类的startServiceLocked方法,下面看看这个方法具体实现:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
// ...
// 关键代码
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
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;
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//...
if (app == null && !permissionsReviewRequired) {
// 关键代码
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, 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";
bringDownServiceLocked(r);
return msg;
}
// ...
}
// ...
return null;
}
这个方法中的mAm.startProcessLocked(),mAm这个变量是AMS,代码跳转到AMS类中执行,下面看看这个方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
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 */);
}
接着调用了startProcessLocked的几个重载方法后,最终调用了startProcess方法,startProcess方法内部会调用Process类的start方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
这个方法内部又调用了ZygoteProcess类的start方法。这个过程是SystemServer进程和ZygoteProcess进程进行通信的过程,它们之间通信是通过Socket进行通信的。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// ...
synchronized(mLock) {
//关键代码
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
zygoteSendArgsAndGetResult方法创建一个App进程。至此,app进程总算创建完成。接着会执行app进程的ActivityThread的main方法。这个main方法是app进程的入口。下面看看ActivityThread类的main方法。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
// ...
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
// ...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// ...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这个方法内部, 主要是准备一个Looper对象,并准备一个消息列表,用于存在主线程的handler发送的消息。并创建一个ActivityThread对象。并调用attach方法,并且,如果sMainThreadHandler为null,给sMainThreadHandler赋值,
并且调用Looper.loop方法循环到从消息队列中抽取消息。下面来看看attach方法的具体实现:
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// ...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
}
// ...
} else {
// ...
}
// ...
}
这个方法中,获取了ActivityManagerServcie在app客户端的代理对象,调用代理对象的attachApplication方法,这时,app进程挂起,SystemServer进程的AMS类的attachApplication方法执行。
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
// ...
//关键代码
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// ...
try {
// ...
if (app.isolatedEntryPoint != null) {
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
}
// ...
}
// ...
// Find any services that should be running in this process...
if (!badApp) {
try {
//关键代码
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// ...
return true;
}
attachApplication方法内部,又继续调用了attachApplicationLocked方法,attachApplicationLocked方法内部,通过IApplicationThread的bindApplication方法,IApplicationThread内部的bindApplication方法内,通过sendMessage(H.BIND_APPLICATION, data),这样ActivityThread内的内部类H,它是继承了Handler的,这样H类的handleMessage方法中的代码执行,这样handleBindApplication()方法就执行了,handleBindApplication()方法主要
做了三件事:
1.创建Instrumentation对象;
2.调用LoadedApk类的makeApplication方法创建Application对象
3.调用Instrumentation对象的callApplicationOnCreate方法
经过上面三个步骤,Application就创建了,并且它的OnCreate方法也执行了。
继续看AMS类的attachApplicationLocked方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// ...
try {
// ...
if (app.isolatedEntryPoint != null) {
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
}
// ...
}
// ...
// Find any services that should be running in this process...
if (!badApp) {
try {
//关键代码
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// ...
return true;
}
这个方法内部,还会继续执行mServices.attachApplicationLocked(app, processName);
mServices是ActiveServices类型的,所以跳转到ActivieServices类中执行
http://androidxref.com/9.0.0_r3/xref/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.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
// ...
//关键代码
realStartServiceLocked(sr, proc, sr.createdFromFg);
// ...
}
}
// ...
}
// ...
return didSomething;
}
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
// ...
boolean created = false;
try {
// ...
//关键代码
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
}
// ...
// 关键代码
sendServiceArgsLocked(r, execInFg, true);
// ...
}
这个方法中的app.thread对象就是ApplicationThread类型的对象,所以跳转到 ApplicationThread类的scheduleCreateService方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
// ...
// 关键代码
sendMessage(H.CREATE_SERVICE, s);
}
public void handleMessage(Message msg) {
// ...
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);
// ...
}
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 {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
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,
ActivityManager.getService());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().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);
}
}
}
scheduleCreateService方法内部最终会调用到handleCreateService方法,
handleCreateService方法内部主要做了如下事情:
1.通过类加载方式创建Service的实例对象
2.调用LoadedApk的makeApplication方法创建Application对象,由于在前面的步骤中已经创建了
Application对象,所在这个方法中,就直接返回之前创建的Application对象。
3.调动Service的attach方法,attach方法内部,主要是调用attachBaseContext,将ContextImpl对象赋值给Service父类的mBase对象。`
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/Service.java
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
//关键代码
attachBaseContext(context);
// ...
}
4.调用Servcie的onCreate方法,这样Service的OnCreate方法就执行了
至此,Servcie创建了并且调用了OnCreate方法,下面继续看看ActiveServices类的realStartServiceLocked方法中的sendServiceArgsLocked方法
http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
// ...
boolean created = false;
try {
// ...
//关键代码
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
}
// ...
// 关键代码
sendServiceArgsLocked(r, execInFg, true);
// ...
}
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
// ...
try {
r.app.thread.scheduleServiceArgs(r, slice);
}
// ...
}
sendServiceArgsLocked方法中的r.app.thread其实就是IApplicationThread类型的对象,所以最终会执行
ApplicationThread类中的scheduleServiceArgs方法,下面来看这个方法具体实现:
http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/app/ActivityThread.java
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
//...
// 关键代码
sendMessage(H.SERVICE_ARGS, s);
}
}
public void handleMessage(Message msg) {
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
// ...
int res;
if (!data.taskRemoved) {
// 关键代码
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
// ...
}
// ...
}
}
handleServiceArgs方法中,执行了Servcie的onStartCommand方法,至此,Service的onStartCommand方法得到执行。
以上便是startServcie启动Servcie的过程分析。