Service的启动分为两种,startService和bindService;
1.StartService
startService启动流程可以分为两步,ContextImpl到AMS,AMS到ActivityThread
ContextImpl到AMS
Service是基于装饰器模式的,装饰器是ContextImpl,被装饰类的接口是ContextWraper,Service是被装饰类,它将startService()请求交给装饰器ContextImpl去处理:
ContextImpl
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
return cn;
}
}
ContextImpl的startServiceCommon()中调用了IActivityManager的startService();上一篇文章提过IActivityManager,这是AMS在用户进程的Binder代理对象;
企业咚咚20200921102802.jpgAMS到ActivityThread
在AMS中,通过一个核心类ActiveServices
来完成Service的启动,主要涉及到三个方法:
-
startServiceInnerLocked():
准备ServiceRecord,ServiceRecord和ProcessRecord,ActivityRecord一样,记录了Service的所有信息; -
bringUpServiceLock():
判断Service运行的进程 -
realStartServiceLocked():
调用app.thread发起Binder通信通知ApplicationThread;
ActivityThread
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中发出了一个Message,H.CREATE_SERVICE
H的处理
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
// 分析1
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 分析2
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
// 分析3
service.onCreate();
mServices.put(data.token, service);
}
}
- 通过ClassLoader构建Service实例对象
- 绑定ContextImpl
- 调用onCreate()
补充:AMS进程的ActiveServices的realStartServiceLocked
中发起了两个Binder通信,一次用于启动Service,一次用于调用onStartCommand();流程和第一次一样,消息是SERVICE_ARGS
;
2. BindService:
BindService也是由ContextImpl发起的,通过用户进程代理iActivityManager传递给AMS,过程和上面一样,重点来看AMS中bindService()的逻辑;
AMS的bindService逻辑都交给了ActiveServices
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
...
// 分析1
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
...
// 分析2
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
- bindService首先调用bringUp去启动Service,这里上文已经说过,和startService一样,
- 第二步通过
requestServiceBindingLocked()
绑定Service的生命周期;
ActiveServices:
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
...
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.repProcState);
...
}
在这里将绑定的请求交给了ActivityThread类的Application;
ActivityThread
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) {
sendMessage(H.BIND_SERVICE, s);
}
H.handleMessage():
case UNBIND_SERVICE:
handlebindService((BindServiceData)msg.obj);
break;
private void handleBindService(BindServiceData data) {
if (s != null) {
try {
// 分析1
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
// 分析2
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
}
- 在这里会根据Service是否启动过调用onBind()或者onRebind()
- 如果没有绑定过,会发出一个binder消息,调用AMS中的 publishService()
publishService最终调用ActiveServices的publishServiceLocked:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
...
c.conn.connected(r.name, service, false);
...
}
c.conn是iServiceConnection,是用户进程的ServiceConnection在AMS进程的代理,他的具体实现是ServiceDispatcher.innerConnection,而ServiceDispatcher是LoadedApk的内部类:
static final class ServiceDispatcher {
...
private static class InnerConnection extends IServiceConnection.Stub {
...
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
...
}
...
}
调用了ServiceDispatcher的connected()
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
在这里发出了一个主线程的Handler消息,发出的是一个Runnable,我们看一下run():
public void run() {
if (mCommand == 0) {
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
public void doConnected(ComponentName name, IBinder service, boolean dead) {
...
mConnection.onServiceConnected(name, service);
...
}
在这里调用了onServiceConnect(),客户端的ServiceConnection会执行相同的回调;
网友评论