Service啓動流程和Activity啓動流程有些類似,不瞭解Activity啓動流程的能夠看我以前的一篇博客Android App啓動過程java
首先咱們先從 context.startService()
這個方法爲起點進行分析,咱們看下他的源碼git
## ContextWrapper.java
public class ContextWrapper extends Context {
public ComponentName startService(Intent service) {
return mBase.startService(service); //其中mBase爲ContextImpl對象
}
}
複製代碼
這個方法又調用了ContextImpl.startService
app
## ContextImpl.java
class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
...
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
複製代碼
咱們看到最後調用了ActivityManagerNative.getDefault().startService
,其中ActivityManagerNative.getDefault()
就是ActivityManagerService
,這時就完成了從調用進程
到system_server進程
,其中是經過Binder
傳輸的信息ide
下面咱們看一下AMS到底作了什麼post
## ActivityManagerService.java
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
····
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
複製代碼
這個方法又調用了ActivityService#startServiceLocked
ui
## ActivityService.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
···
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
ServiceRecord r = res.record;
···
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
複製代碼
繼續調用了ActivityService#startServiceInnerLocked
this
## ActivityService.java
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
···
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
···
return r.name;
}
複製代碼
繼續調用了ActivityService#bringUpServiceLocked
spa
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException {
···
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
//若是Service進程存在
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//啓動Service
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
}
//若是不存在此進程,則
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";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
return null;
}
複製代碼
這個方法主要作了倆件事線程
realStartServiceLocked
startProcessLocked
方法建立進程,進過層層的調用,最終會調用到AMS.attachApplicationLocked
方法,而後執行realStartServiceLocked
方法private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
...
if (!badApp) {
try {
//尋找全部須要在該進程中運行的服務
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
...
return true;
}
複製代碼
繼續調用 AS.attachApplicationLocked
rest
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException {
boolean didSomething = false;
...
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
mAm.mProcessStats);
//啓動Service
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
...
}
}
複製代碼
這個方法調用了realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
...
}
複製代碼
這個方法內部調用了app.thread.scheduleCreateService
,而app.thread
是IApplicationThread
類型的,他的實現是ActivityThread
的內部類ApplicationThread
是一個Binder
,下面咱們看一下ApplicationThread#scheduleCreateService
這個方法
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);
}
複製代碼
這個方法實際上是發送了一個消息給Handler
,這個Handler
是ActivityThread
的內部類H
class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
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;
}
}
複製代碼
最終調用了handleCreateService
方法
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//獲取類加載器
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//加載Service實例
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//建立Service的Context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//初始化Service
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//調用Service的onCreate方法
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);
}
}
}
複製代碼
到這裏Service就啓動完成了
整個StartService
過程,從進程的角度看Service
的啓動流程
ProcessA
進程採用Binder
形式向syster_server
進程發起startService
請求syster_server
進程收到請求後,向zygote
進程發送建立進程的請求zygote
進程fork
出新的進程,進出新進程的ActivityThread
的main
方法Binder
向syster_server
進程發起attachApplication
請求syster_server
進程收到請求後,進過一系列的準備後,經過Binder
向新進程發送scheduleCreateService
請求Handler
發送CREATE_SERVICE
消息Service
,並回調onCreate