共计 12101 个字符,预计需要花费 31 分钟才能阅读完成。
前言
因为源码剖析的代码量比拟大,大部分博客网站的内容显示页面都比拟窄,显示进去的成果都异样俊俏,所以您也能够间接查看《Thinking in Android》来浏览这边文章,心愿这篇文章能帮你梳理分明 “Service 的启动流程”。
外围源码
要害类 | 门路 |
---|---|
ContextImpl.java | frameworks/base/core/java/android/app/ContextImpl.java |
ContextWrapper.java | frameworks/base/core/java/android/content/ContextWrapper.java |
ContextThemeWrapper.java | frameworks/base/core/java/android/view/ContextThemeWrapper.java |
Activity.java | frameworks/base/core/java/android/app/Activity.java |
ActivityManager.java | frameworks/base/core/java/android/app/ActivityManager.java |
ActivityManagerService.java | frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java |
ActiveServices.java | frameworks/base/services/core/java/com/android/server/am/ActiveServices.java |
ActivityThread.java | frameworks/base/core/java/android/app/ActivityThread.java |
Service
的启动过程绝对 Activity
的启动过程来说简略了很多,咱们都晓得怎么去创立和启动一个 Service,那么你有没有从源码角度钻研过 Service 启动后在零碎层是如何运作的?
Activity.startService()
首先咱们晓得:要启动一个 Service 的时候,个别都是在 Activity 中通过 startService()
来启动:
Intent intent = new Intent(MainActivity.this, xxxService.class);
startService(intent);
然而咱们在 Activity
源码中并没有实现 startService()
办法,那它在哪里被调用的?找不到咱们就去 Activity
的父类中找。
// frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient { }
// frameworks/base/core/java/android/view/ContextThemeWrapper.java
public class ContextThemeWrapper extends ContextWrapper {
}
// frameworks/base/core/java/android/content/ContextWrapper.java
public class ContextWrapper extends Context {}
Activity
继承了 ContextThemeWrapper
类,ContextThemeWrapper
又继承了 ContextWrapper
类,ContextWrapper
又继承了 Context
类。
ContextWrapper.startService()
在 ContextWrapper
中实现了 startService()
办法:
// frameworks/base/core/java/android/content/ContextWrapper.java
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {mBase = base;}
@Override
public ComponentName startService(Intent service) {return mBase.startService(service);
}
}
所以 startService()
办法其实是由 ContextWrapper
实现的,紧接着又调用了 mBase.startService()
办法,mBase
对象是 Context
的子类 ContextImpl
,所以调用最终进入 ContextImpl
类的 startService()
办法。
ContextImpl.startService()
// frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
try {validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// 通过 Binder 过程间通信进入 ActivityManagerService 的 startService() 办法
ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier());
... ...
return cn;
} catch (RemoteException e) {throw e.rethrowFromSystemServer();
}
}
}
ActivityManager.getService()
// frameworks/base/core/java/android/app/ActivityManager.java
public class ActivityManager {
@UnsupportedAppUsage
public static IActivityManager getService() {return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
}
ActivityManagerService.startService()
接下来就执行到 ActivityManagerService
的 startService()
办法:
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ActiveServices mServices;
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 {// 调用 ActiveServices 的 startServiceLocked() 办法
res = mServices.startServiceLocked(caller, service, resolvedType, callingPid,
callingUid, requireForeground, callingPackage, userId);
} finally {Binder.restoreCallingIdentity(origId);
}
return res;
}
}
}
ActiveServices.startServiceLocked()
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
final int userId, boolean allowBackgroundActivityStarts)
throws TransactionTooLargeException {
... ...
// 解析 AndroidManifest.xml 文件中配置 Service 的 intent-filter 相干内容信息
ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
if (res == null) {return null;}
... ...
ServiceRecord r = res.record;
... ...
// 调用 startServiceInnerLocked() 办法
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
}
通过 retrieveServiceLocked()
办法来解析 AndroidManifest.xml
文件中配置 Service 的 intent-filter
相干内容信息。
当解析完 Service
的 intent-filter
相干内容信息后,解析的后果会保留在 res.record
变量中。而 res 变量是一个 ServiceLookupResult
类型的对象,它的 record 变量则是一个 ServiceRecord
类型对象,用来示意一个 Service
。
ActiveServices.startServiceInnerLocked()
ActiveServices 的 startServiceLocked() 办法最初调用了 startServiceInnerLocked()
办法:
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
... ...
// 调用 bringUpServiceLocked() 办法
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
... ...
}
}
ActiveServices.bringUpServiceLocked()
调用 bringUpServiceLocked()
办法进一步解决:
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
... ...
ProcessRecord app;
if (!isolated) {app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); // 获取 app 对象
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + "app=" + app);
if (app != null && app.thread != null) {
try {app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
// 运行 service 的过程曾经启动,调用 realStartServiceLocked() 办法
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {throw e;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting service" + r.shortInstanceName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {... ...}
// 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,
hostingRecord, 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;
}
}
bringUpServiceLocked()
办法首先通过 getProcessRecordLocked()
办法去获取 app 对象,它是一个 ProcessRecord
类型的对象,如果它不为空,阐明 Service
要运行的过程曾经存在。
Service 运行的过程有两种:
(1)一种是默认的,即运行在 Activity 启动 Service 的那个过程里,也就是说在哪个过程里调用了 startService() 办法,启动的 service 就运行在哪个过程里。
(2)一种是给 Service 一个独自的过程运行,比方在 AndroidManifest 文件里配置了如下内容:
//
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.documentsui">
<application
android:name=".DocumentsApplication"
android:label="@string/app_label"
android:icon="@drawable/app_icon"
android:supportsRtl="true"
android:allowBackup="true"
android:backupAgent=".prefs.BackupAgent"
android:fullBackupOnly="false">
<!-- Run FileOperationService in a separate process so that we can use FileLock class to
wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
details. -->
<service
android:name=".services.FileOperationService"
android:exported="false"
android:process=":com.android.documentsui.services">
</service>
</application>
</manifest>
在这段配置里有 android:process="xxx"
申明,这个申明用来实现 service 独自运行在 “xxx” 过程里。这样做的益处是,即便应用程序无奈工作,因为 service 独自运行在一个过程里,所以会持续工作
。
回到后面的办法,如果变量 app 为空,就代表 service 要运行的过程还没有启动,于是调用 startProcessLocked()
办法去启动一个新的过程。
如果 app 不为空,采纳默认的形式启动 Service,最终调用到 realStartServiceLocked()
办法:
ActiveServices.realStartServiceLocked()
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
... ...
try {
... ...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo), app.getReportedProcState());
... ...
}
... ...
}
}
在这个办法中,app 对象的 thread
变量是一个 ApplicationThread
Binder
对象,调用它的 scheduleCreateService()
办法之后,会进入客户端的 ActivityThread
中。
ActivityThread.scheduleCreateService()
// frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {
// ApplicationThread 是一个 Binder
private class ApplicationThread extends IApplicationThread.Stub {
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
的 scheduleCreateService()
办法通过调用 sendMessage() 办法来发送一个 msg 音讯
,当 Handler 接管到了 msg 音讯之后,它会调用 handleCreateService()
办法来做进一步解决。
H.handleMessage()
// frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {
class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate:" + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj); // 调用 handleCreateService() 办法
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}
ActivityThread.handleCreateService()
// frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {private void handleCreateService(CreateServiceData data) {
... ...
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 {if (localLOGV) Slog.v(TAG, "Creating service" + data.info.name);
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(); // 进入 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);
}
}
}
}
在 ActivityThread
类的 handleCreateService()
办法中,首先通过 ClassLoader
类把 Service 加载进来,而参数 data.info.name
示意这个 Service
的名字,instantiateService()
办法是创立一个 Service 实例。接着,创立一个 Context 对象
,作为上下文环境之用。
handleCreateService()
办法最初调用了 service 的 onCreate() 办法
,当这个办法被调用之后, 就会进入应用程序里 Service 的 onCreate() 办法
。
至此,Service 的启动就剖析结束,这个过程与启动 Activity 相比简略了很多。