【Framework】bindService启动流程

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

前言

【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)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值