1.AMS的bindService

我们从调用bindService方法开始来看

bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);

我们点击进入bindService方法,进入到了Context中的bindService中,而这个方法是一个抽象方法,而这个方法的具体实现其实是ContextWrapper中,所以我们直接看ContextWrapper的bindService方法

@Overridepublic boolean bindService(Intent service, ServiceConnection conn,int flags) {return mBase.bindService(service, conn, flags);}

我们可以看到在ContextWrapper中的bindService又调用了mBase的bindService方法,mBase是Context类型,是一个抽象类,具体的实现类是ContextImpl,所以我们看ContextImpl中的bindService方法

    @Overridepublic boolean bindService(Intent service, ServiceConnection conn,int flags) {warnIfCallingFromSystemProcess();return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),Process.myUserHandle());}

调用了bindServiceCommon方法

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handlerhandler, UserHandle user) {...try {...int res = ActivityManager.getService().bindService(mMainThread.getApplicationThread(), getActivityToken(), service,service.resolveTypeIfNeeded(getContentResolver()),sd, flags, getOpPackageName(), user.getIdentifier());...} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

在这个方法中,我们清楚的看见调用了ActivityManager.getService方法,我们看下getService方法:

    public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};

和Android7.0相比,这里有了明显的不同:Android7.0中,create方法中通过asInstance方法来获取IActivityManager对象的,并且可以进出查看asInstance方法,返回的对象为ActivityManagerProxy类;而这里的asInterface方法是IActivityManager.Stub持有的方法,并且查看不了,因为Android8.0之后使用了IActivityManager是使用AIDL进行生成的,细节被隐藏了。了解Android7.0的同学应该知道,这里实现的功能和Android7.0实现的功能是一样的,不了解的话可以先阅读我的上篇文章Android7.0 bindService源码解析_紫气东来_life的博客-CSDN博客

所以能,我们直接看AMS的bindService方法即可

2.Service的绑定过程

接着上面的,我们看AMS的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);}}

mService是ActiveServices,我们看ActiveServices的bindServiceLocked方法

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,String resolvedType, final IServiceConnection connection, int flags,String callingPackage, final int userId) throws TransactionTooLargeException {...try {....if (s.app != null && b.intent.received) {....if (b.intent.apps.size() == 1 && b.intent.doRebind) {requestServiceBindingLocked(s, b.intent, callerFg, true);}} else if (!b.intent.requested) {requestServiceBindingLocked(s, b.intent, callerFg, false);}}
}

这里的代码很多,我阉割了无关的代码。调用requestServiceBindingLocked方法,并且第三个参数是为false,第三个参数是rebind,重新绑定的意思,我们看下代码

    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,boolean execInFg, boolean rebind) throws TransactionTooLargeException {...if ((!i.requested || rebind) && i.apps.size() > 0) {try {bumpServiceExecutingLocked(r, execInFg, "bind");r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.repProcState);if (!rebind) {i.requested = true;}i.hasBound = true;i.doRebind = false;} ...}return true;}

我们可以看到,调用了thread的scheduleBindService方法,这里thread其实就是ActivityThread,所以我们直接到ActivityThread中寻找scheduleBindService方法

        public final void scheduleBindService(IBinder token, Intent intent,boolean rebind, int processState) {...sendMessage(H.BIND_SERVICE, s);}

sendMessage方法大家应该比较熟悉,所以直接找到接收H.BIND_SERVICE的地方就行了,同样是在ActivityThread方法中,如下:

                case BIND_SERVICE:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");handleBindService((BindServiceData)msg.obj);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;

查看handleBindService方法

    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);ActivityManagerNative.getDefault().publishService(data.token, data.intent, binder);} else {...}ensureJitEnabled();} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}} catch (Exception e) {...}}}

上面我们说了,ActivityManagerNative.getDefault是ActivityManagerProxy,所以我们直接看这个类的publishService方法

    public void publishService(IBinder token,Intent intent, IBinder service) throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(token);intent.writeToParcel(data, 0);data.writeStrongBinder(service);mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);reply.readException();data.recycle();reply.recycle();}

查看接收PUBLISH_SERVICE_TRANSACTION的地方,还是在ActivityManagerNative中

        case PUBLISH_SERVICE_TRANSACTION: {data.enforceInterface(IActivityManager.descriptor);IBinder token = data.readStrongBinder();Intent intent = Intent.CREATOR.createFromParcel(data);IBinder service = data.readStrongBinder();publishService(token, intent, service);reply.writeNoException();return true;}

publishService的方法是在AMS中实现的,和之前的bindService是一样的,我们查看publishService方法

public void publishService(IBinder token, Intent intent, IBinder service) {...synchronized(this) {....mServices.publishServiceLocked((ServiceRecord)token, intent, service);}}

查看publishServiceLocked方法

    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {...c.conn.connected(r.name, service);...}

关键的方法如上,这里的conn是IServiceConnection,而具体的实现类是LoadedApk.ServiceDispatcher,我们在ContextImpl的bindServiceCommon可以找到,如下

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handlerhandler, UserHandle user) {...if (mPackageInfo != null) {sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);}...}

感兴趣的同学可以从这里去递进的查找,我这里就不贴代码了,最后会调用到LoadedApk.ServiceDispatcher的doConnected方法,如下:

        public void doConnected(ComponentName name, IBinder service) {...// If there is a new service, it is now connected.if (service != null) {mConnection.onServiceConnected(name, service);}}

mConnection就是我们调用bindService时传入的ServiceConnection,绑定成功后,从这里回调

bindService到此结束了

Android8.0 bindService源码解析相关推荐

  1. Android7.0 bindService源码解析

    看到标题的时候,有些同学可能会有些质疑:现在都Android12了,你讲Android7,是不是太过时了.这里有两个原因: (1)Android8.0和Android7.0的源码有些不同,但是Andr ...

  2. EventBus1.0.1源码解析

    很久没有更新过源码解析类文章,以下内容作为源码分析类的笔记.分析方法适用于其它源码分析. 分析工具说明 许久以来,阅读源代码最得力的工具就非Source Insight莫属了.然,后来微软出了一款轻量 ...

  3. Ubuntu16.04编译Android8.0系统源码,并刷机 (Pixel XL)

    机子 CPU: 6核 内存: 16G 硬盘:500G SSD 系统:裸的 Ubuntu 16.04 试了Mac和Ubuntu 14.04,Mac中需要安装一堆工具,Ubuntu 14安装Java8很麻 ...

  4. YYModel V1.0.4源码解析

    YYKit出现了很长时间了,一直想要详细解析一下它的源码,都是各种缘由推迟了. 最近稍微闲了一点,决定先从最简单的YYModel开始吧. 首先,我也先去搜索了一下YYModel相关的文章,解析主要AP ...

  5. 部署测试fabric1.0及源码解析

    开发环境 UBUNTU 16.04 LTS docker docker-compose git go 1.8以上 docker,docker-compose以及go的安装这里不再描述. 部署测试 新建 ...

  6. android9.0 UsbService源码解析

    文章目录 前言 一.服务启动 二.服务创建 三.系统就绪 四.系统启动完毕 前言 USBManager作为一接口类,客户端,当然要有一个服务端来支持工作,这个服务就是UsbService.我这里先从他 ...

  7. android9.0 UsbManager源码解析

    文章目录 前言 一.UsbManager是什么? 二.每个类的简介 总结 前言 安卓手机可以通过USB连接外设,比如键盘,鼠标,摄像头.还可以与电脑互联进行数据传输,加强了对外扩展的能力. 这功能无疑 ...

  8. react native 0.50 源码解析 再出发 持续更新

    1.核心类 1.1 RCTRootView 一个RCTRootView持有一个RCTBridge成员变量 RCTRootView : UIViewRCTBridge *bridge;UIViewCon ...

  9. [Dubbo3.0.8源码解析系列]-12-全局视野来看Dubbo3.0.8的服务启动生命周期

    目录 12 全局视野来看Dubbo3的服务启动生命周期 12.1 启动方法简介 12.2 启动器启动方法的调用逻辑start() 12.3 应用程序发布器DefaultApplicationDeplo ...

最新文章

  1. 初步认识Volatile-JMM
  2. 从0实现三层神经网络
  3. 蓝牙耳机按键事件linux,调用蓝牙耳机的按键,或者有线耳机的按键方法?
  4. 小米4刷CM13系统
  5. 用异或的性质实现简单加密解密
  6. mysql-数据备份操作
  7. 百度关键词抓取工具_手把手教你百度霸屏引流 三大核心推广技巧 人人可操作...
  8. 计算机控制系统电阻加热课设,计算机控制系统课程设计资料.doc
  9. SnakeMaker:模仿实现 即刻APP 头像拖动的残影效果
  10. [渝粤教育] 中国地质大学 国际贸易实务 复习题
  11. 百度搜索引擎的搜索高级语法及应用
  12. 为ESP8266编译时出错
  13. amd 服务器cpu型号怎么看,怎么看CPU是几代的?intel和AMD怎么区分CPU是第几代的方法...
  14. python计算三个点构成的三角形的外切圆圆心坐标及半径
  15. 计算机基础知识键盘知识,计算机基础知识:键盘的布局
  16. WordPress优化教程大全
  17. 《Kubernetes证书篇:使用TLS bootstrapping简化kubelet证书制作》
  18. oracle通信通道的文件结尾_Oracle错误——ORA-03113:通信通道的文件结尾 解决办法...
  19. 单机魔兽世界服务器显示不兼容,官网公告:解决登陆游戏设备驱动不兼容问题...
  20. 外包公司面试门槛高吗?程序员进外包公司容易吗?

热门文章

  1. 4-4.stm32之LCD XPT2046的使用
  2. [Python从零到壹] 六十一.图像识别及经典案例篇之基于纹理背景和聚类算法的图像分割
  3. 数据库中数据长度到底代表什么呢?
  4. 【程序员面试金典】登峰造极--判定字符是否唯一
  5. 启动hadoop集群报错ERROR: Cannot set priority of namenode process 2570
  6. 万维网服务器的传送协议,万维网WWW和超文本传送协议HTTP
  7. excel版本问题解决方案
  8. 算法 4:支持向量机
  9. 体验学习的快乐.体会进步的喜悦!
  10. 基于TensorFlow Object Detection API训练自己的目标识别模型