介绍
Service的工作状态分为启动状态和绑定状态,启动状态主要用于后台计算,绑定状态可以用于其他组件和Service的交互。分别看一下这两种状态的启动流程。
Intent serviceIntent = new Intent(this, SampleService.class);
//启动Service
startService(serviceIntent);
//绑定Service
bindService(serviceIntent,mServiceConnection,BIND_AUTO_CREATE);
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
源码分析
Service启动过程
调用ContextWrapper的startService方法
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
mBase是Context的实现类ContextImpl
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
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;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
这里调用了ActivityManagerService的startService方法
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
//...
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
//...
}
调用ActiveServices的startServiceLocked
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);
//...
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//...
realStartServiceLocked(r, app, execInFg);
//...
}
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);
//...
sendServiceArgsLocked(r, execInFg, true);
//...
}
我们又看到了app.thread对象,跟Activity的启动类似的,这里又来到了ApplicationThread中
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);
}
这里也是发送一个启动Service的消息到H,我们直接看对该消息的处理
public void handleMessage(Message msg) {
//...
case CREATE_SERVICE:
//...
handleCreateService((CreateServiceData)msg.obj);
//...
break;
}
private void handleCreateService(CreateServiceData data) {
//...
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
//...
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);
//...
}
在handleCreateService方法中,首先使用类加载器创建Service,然后创建了ContextImpl对象,同样的也调用了Service的attach方法为Service中关键参数赋值,最后回调了onCreate方法。
在realStartServiceLocked中sendServiceArgsLocked还会调用ApplicationThread的scheduleServiceArgs方法,最后又调用了handleServiceArgs方法
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
//...
res = s.onStartCommand(data.args, data.flags, data.startId);
//...
}
在Service启动后,这里又回调了onStartCommand方法,到这里Service启动流程就结束了。
Service绑定流程
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
具体实现同样是交给了ContextImpl
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
//...
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else {
throw new RuntimeException("Not supported in system context");
}
//...
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
//...
}
这里将ServiceConnection对象转换为ServiceDispatcher.InnerConnection,由于服务绑定可能是跨进程的,因此ServiceConnection需要借助Binder让远程服务端回调自己的方法,而ServiceDispatcher.InnerConnection就充当这个角色。
调用ActivityManagerService的bindService
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
//...
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
调用ActiveServices的bindServiceLocked
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
//...
bringUpServiceLocked(serviceRecord,serviceIntent.getFlags(),callerFg, false, false);
//...
requestServiceBindingLocked(s, b.intent, callerFg, true);
//
}
bringUpServiceLocked启动Service已经分析了,会经过AMS完成Service的创建。这里看requestServiceBindingLocked
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);
//...
}
调用ApplicationThread的scheduleBindService,这里还是发送消息让Handler处理,我们直接看处理的方法
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(data.token, data.intent, binder);
//...
}
//...
}
这里调用Service的onBind方法,然后调用AMS的publishService
public void publishService(IBinder token, Intent intent, IBinder service) {
//...
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
//...
}
调用ActiveServices的publishServiceLocked
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
//...
c.conn.connected(r.name, service, false);
//...
}
c.conn是ServiceDispatcher.InnerConnection对象
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);
}
}
这里mActivityThread是ActivityThread里的H这个Handler,RunConnection是一个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) {
//...
if (service != null) {
mConnection.onServiceConnected(name, service);
}
//...
}
最后回到了ServiceConnection的onServiceConnected方法,且他运行在主线程中,这样Service的绑定过程就完成了。
网友评论