bindService(service, conn, flags)-->在Application/Activity中调用context.bindService,context都是Application/Activity的attch中传入的ContextImpl
Context-->bindService
ContextImpl-->bindService
< Context 的 bindService是怎么调到 ContextImpl中的bindService
首先 Activity/Service/Application 这些是继承ContextWrapper
ContextWrapper extends Context 会重写bindService方法,调用 mBase.bindService()
其中mBase就是ContextImpl (ContextImpl extends Context)>
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, String instanceName, Handler handler, Executor executor, UserHandle user) {
IServiceConnection sd;
……
// sd其实指向的是一个ServiceDispatch.InnerConnection的对象
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
……
//ActivityManager.getService()获取IActivityManager,可以直接向ActivityManagerService发送IPC消息
//上面这个sd是为了跨进程回传信息用:最终通过这个对象调用ServiceConnection的onServiceConnected()方法
int res = ActivityManager.getService().bindIsolatedService(this.mMainThread.getApplicationThread(),
this.getActivityToken(), service, service.resolveTypeIfNeeded(this.getContentResolver()), sd, flags,
instanceName,this.getOpPackageName(), user.getIdentifier());
……
}
这里面有两个比较重要的方法
1. 获取IServiceConnection实例 InnerConnection,<--下面会讲为什么
LoadedApk --> getServiceDispatcher-->getServiceDispatcherCommon
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Executor executor, int flags) {
return getServiceDispatcherCommon(c, context, null, executor, flags);
}
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {
……
LoadedApk.ServiceDispatcher sd = null;
sd = new ServiceDispatcher(c, context, handler, flags);
……
return sd.getIServiceConnection();
}
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
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);
}
}
}
@UnsupportedAppUsage
ServiceDispatcher(ServiceConnection conn,Context context, Handler activityThread, int flags) {
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
……
}
@UnsupportedAppUsage
IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
}
这里讲一下为什么说InnerConnection是IServiceConnection的实例
InnerConnection extends IServiceConnection.Stub
IServiceConnection.Stub extends Binder implements IServiceConnection
所以说InnerConnection是IServiceConnection的实例,看下面的代码
public interface IServiceConnection extends IInterface {
@UnsupportedAppUsage
void connected(ComponentName var1, IBinder var2, boolean var3) throws RemoteException;
public abstract static class Stub extends Binder implements IServiceConnection {
……
}
2. 第二个重点方法 ActivityManagerService-->bindIsolatedService
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
……
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
继续往下走,注意看代码里的注释
ActiveServices-->bindServiceLocked-->bringUpServiceLocked-->realStartServiceLocked
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
……
//根据用户传递进来Intent来检索相对应的服务
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
callerFg, isBindExternal, allowInstant);
……
ServiceRecord s = res.record;
……
//创建AppBindRecord对象记录着当前ServiceRecord,intent以及发起方的进程信息
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
……
//如果bindService 的时候置上flag Context.BIND_AUTO_CREATE,那么会直接进入bringUpServiceLocked() 进行唤醒。
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
//此方法中会判断是否首次bindService,如果是,则直接return 0;不会向下执行,
//如果不是首次bind,则向下执行逻辑,直接回调connected
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
……
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
// c.conn就是上文中我们提到的ServiceDispatcher.InnerConnection的对象
// 如果Service正在运行,通过此对象跨进程 调用他的connected()方法,此connected()中的逻辑下文会体现
// (另外在下文中在首次bindService时publishServiceLocked中也会调用connected())
try {
c.conn.connected(s.name, b.intent.binder, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + s.shortInstanceName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
}
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//由本方法的参数可知,r是ServiceRecord的对象,ServiceRecord代表着一个Service记录
//联系整个Service的启动过程可知:
//首次调用bindService()启动一个Service时候,r.app应该为null,(是在realStartServiceLocked中赋值的)下面的if判断不成立
// 如果不是首次调用bindService()方法,则下面的if判断成立,调用 sendServiceArgsLocked()方法,然后return
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
……
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
……
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
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.
}
……
}
realStartServiceLocked中有两个比较重要的方法
realStartServiceLocked-->app.thread.scheduleCreateService
realStartServiceLocked-->requestServiceBindingsLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
……
//在此方法中给r.app赋值
r.setProcess(app);
……
//app.thread其实就是ActivityThread中ApplicationThread类的对象,
//调用ApplicationThread的scheduleCreateService()方法
//其实该方法就最终会调用到Service的onCreate()方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
……
//该方法是通过bindService()绑定Service的时候才去真正的调用,从而调用onBind()方法
//当通过startService()方法来开启一个Service的时候,该方法内部的逻辑不成立
//稍后会介绍这个方法的内容
requestServiceBindingsLocked(r, execInFg);
……
}
1. realStartServiceLocked-->app.thread.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);
}
H处理message
public void handleMessage(Message msg) {
……
switch (msg.what) {
……
case CREATE_SERVICE:
……
handleCreateService((CreateServiceData)msg.obj);
……
break;
……
}
……
}
private void handleCreateService(CreateServiceData data) {
……
Service service = null;
try {
……
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
……
//这里把ContextImpl传递进service
service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
service.onCreate();
……
} catch (Exception e) {
……
}
……
}
2. realStartServiceLocked-->requestServiceBindingsLocked
requestServiceBindingsLocked->requestServiceBindingLocked-->r.app.thread.scheduleBindService
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
……
//细节,在这个方法中会有调用scheduleServiceTimeoutLocked 这个是ANR超时逻辑,前台服务20s,后台200s
//然后会在在绑定成功后调用ActiveServices中的serviceDoneExecutingLocked解除ANR监听,下文有体现
bumpServiceExecutingLocked(r, execInFg, "bind");
//app.thread其实就是ActivityThread中ApplicationThread类的对象,
//调用ApplicationThread的scheduleBindService()方法
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.getReportedProcState());
……
return true;
}
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {4
……
scheduleServiceTimeoutLocked(r.app);
……
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
//这个是ANR超时逻辑,前台服务20s,后台200s
mAm.mHandler.sendMessageDelayed(msg, proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
继续往下
ApplicationThread->scheduleBindService-->sendMessage(H.BIND_SERVICE, s)
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
……
sendMessage(H.BIND_SERVICE, s);
}
H处理message -->handleBindService--> ActivityManager.getService().publishService
public void handleMessage(Message msg) {
……
switch (msg.what) {
……
case BIND_SERVICE:
……
handleBindService((BindServiceData)msg.obj);
……
break;
……
}
……
}
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
……
if (s != null) {
try {
……
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
//在绑定成功后解除ANR监听
//最终会调到 ActiveServices中的serviceDoneExecutingLocked
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
……
}
} catch (Exception e) {
……
}
}
}
ActivityManagerService->publishService
public void publishService(IBinder token, Intent intent, IBinder service) {
……
synchronized(this) {
……
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
ActiveServices->publishServiceLocked
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
……
//数据connections是在bindServiceLocked中添加的
ArrayMap> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList clist = connections.valueAt(conni);
for (int i=0; i
回顾一下 ServiceDispatcher.InnerConnection的创建过程
ContextImpl-->bindServiceCommon-->mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
mPackageInfo就是 LoadedApk
LoadedApk-->getServiceDispatcher-->getServiceDispatcherCommon-->IServiceConnection的实例ServiceDispatcher.InnerConnection
所以
c.conn.connected-->InnerConnection中的 connected(ComponentName name, IBinder service, boolean dead)
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
LoadedApk.ServiceDispatcher-->connected-->doConnected
public void connected(ComponentName name, IBinder service, boolean dead) {
//RunConnection()中最终也会调用到doConnected中
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
private final ServiceConnection mConnection;
public void doConnected(ComponentName name, IBinder service, boolean dead) {
……
// If there was an old service, it is now disconnected.
//如果不为null,取消和旧的Service的连接
if (old != null) {
mConnection.onServiceDisconnected(name);
}
//根据上文传值dead为false
if (dead) {
mConnection.onBindingDied(name);
}
// If there is a new viable service, it is now connected.
// 建立新的连接
if (service != null) {
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
mConnection.onServiceConnected(name, service);
此方法就是bindservice中的回调方法
至此bindService流程完事。