前言
在【Service启动流程之startService】 中,我们已经分析了startService的流程,这篇就继续讲bindService的流程,他们两有很多相似之处。同样,流程图在总结处。
我们在调用bindService方法时候,实际调用的是ContextImpl的实现。
1. ContextImpl
代码路径:frameworks\base\core\java\android\app\ContextImpl.java
1.1 bindService
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
1.2 bindServiceCommon
private boolean bindServiceCommon(Intent service, ServiceConnection conn,
int flags, String instanceName, Handler handler,
Executor executor, UserHandle user) {
IServiceConnection sd;
if (mPackageInfo != null) {
// 将ServiceConnection 通过LoadedApk包装到 ServiceDispatcher 中
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
}
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess(this);
// 调用 AMS 接口
int res = ActivityManager.getService().bindServiceInstance(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2. LoaderApk
代码路径:frameworks\base\core\java\android\app\LoadedApk.java
getServiceDispatcher 直接调用getServiceDispatcherCommon 方法
2.1 getServiceDispatcherCommon
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
if (executor != null) {
// 将ServiceConnection 保存到ServiceDispatcher中
sd = new ServiceDispatcher(c, context, executor, flags);
} else {
sd = new ServiceDispatcher(c, context, handler, flags);
}
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd)

文章详细阐述了Android系统中bindService的执行流程,从ContextImpl的bindService方法开始,经过LoadedApk、ActivityManagerService、ActiveServices等多个关键组件,最终到Service的onBind方法调用和服务连接的建立。过程中涉及到ServiceRecord、ConnectionRecord等数据结构以及ServiceConnection的回调机制。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



