1. bindService
的大致工作流程(客户端调用:客户端调用 bindService 方法-> bindService 请求通过 Binder 机制发送到 ActivityManagerService (AMS)->启动或查找Service:AMS检查 Service 是否已启动,若未启动则启动它,然后将客户端与 Service 绑定。->建立连接:AMS通知 Service 调用 onBind 方法, onBind 返回一个 IBinder 对象。->返回IBinder:AMS将 IBinder 对象传递给客户端的 ServiceConnection 的 onServiceConnected 方法,客户端获得与 Service 通信的接口)
bindService
的核心目标是建立客户端组件(如 Activity)与 Service 的通信通道(通过 IBinder
接口),其流程如下:
步骤说明
-
客户端调用
bindService
-
入口方法:客户端(如 Activity)调用
bindService(Intent, ServiceConnection, flags)
。 -
ContextImpl 转发请求:通过
ContextImpl.bindServiceCommon()
将请求转发至 AMS(ActivityManagerService
)。
// ContextImpl.java boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags) { // 将请求转发给 AMS int res = ActivityManager.getService().bindService(...); return res != 0; }
-
-
AMS 处理绑定请求
-
Service 生命周期管理:
-
若 Service 未运行,AMS 触发其创建:
onCreate()
→onBind()
。 -
若 Service 已运行,直接调用
onBind()
(若已绑定过,可能复用之前的IBinder
)。
-
-
跨进程调度:若 Service 运行在其他进程,AMS 通过 Binder 通知目标进程的
ApplicationThread
创建并绑定 Service。
-
-
Service 返回
IBinder
接口-
Service 实现
onBind
:Service 的onBind()
方法返回IBinder
对象(自定义接口的实现)。
public class MyService extends Service { private final IBinder binder = new MyBinder(); @Override public IBinder onBind(Intent intent) { return binder; // 返回 IBinder 实例 } }
-
-
AMS 回调客户端
-
传递
IBinder
:AMS 将IBinder
封装为BinderProxy
(跨进程时),通过ServiceConnection.onServiceConnected()
回调客户端。 -
客户端接收接口:客户端在回调中转换
IBinder
为具体接口,进行跨进程或同进程通信。
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 转换 IBinder 为自定义接口 MyBinder binder = MyBinder.Stub.asInterface(service); } };
-
关键通信链路
客户端 → ContextImpl → AMS → (跨进程时)Binder驱动 → Service进程 → onBind() → IBinder → AMS → 客户端回调
Service绑定相关的生命周期回调原理
_
客户端绑定:调用 bindService 时,若 Service 未创建,会依次调用 onCreate 和 onBind ;若已创建则直接调用 onBind 。
_
连接成功: Service 的 onBind 返回 IBinder 后,客户端的 ServiceConnection 的 onServiceConnected 被调用。
_
客户端解绑:调用 unbindService , Service 的 onUnbind 方法被调用。若没有其他客户端绑定, Service 会调用 onDestroy 销毁。
_
异常断开:若连接异常断开,客户端的 ServiceConnection 的 onServiceDisconnected 会被调用。
回调顺序与条件
-
首次绑定:
onCreate() → onBind() → ServiceConnection.onServiceConnected()
-
解绑后重新绑定:
-
若
onUnbind()
返回true
:onRebind() → ServiceConnection.onServiceConnected()
-
若
onUnbind()
返回false
或 Service 被销毁:onCreate() → onBind() → ServiceConnection.onServiceConnected()
-
-
完全解绑:
onUnbind() → onDestroy()
生命周期回调方法
回调方法 触发时机 作用 onCreate()
Service 首次创建时触发(无论通过 startService
或bindService
启动)。初始化资源(如线程、数据库连接)。 onBind()
客户端首次调用 bindService
时触发(仅一次,后续绑定复用同一IBinder
)。返回 IBinder
接口,建立通信通道。onUnbind()
所有客户端调用 unbindService()
后触发。清理绑定相关资源。若返回 true
,下次绑定会触发onRebind()
而非onBind()
。onRebind()
当 Service 未被销毁且 onUnbind()
返回true
时,新客户端绑定触发。重新绑定场景下的优化(避免重复初始化)。 onDestroy()
所有客户端解绑且未被 startService
启动时触发。释放所有资源,终止服务。