h5网站开发软件,免费申请激活码,网校培训,大学生简历制作网站一、组件职责与定位
组件所在进程核心职责关键特性CallsManagerTelecom系统进程通话状态机核心#xff1a;管理所有Call对象的生命周期#xff08;创建、状态更新、销毁#xff09;。监听Call状态变化并通知所有观察者#xff08;如InCallController#xff09;。通过mLi…一、组件职责与定位
组件所在进程核心职责关键特性CallsManagerTelecom系统进程通话状态机核心管理所有Call对象的生命周期创建、状态更新、销毁。监听Call状态变化并通知所有观察者如InCallController。通过mListeners集合维护观察者列表如InCallController、Ringer等。InCallControllerTelecom系统进程跨进程通信桥梁监听CallsManager的Call事件绑定InCallService服务如InCallServiceImpl。将Call状态封装为ParcelableCall对象传递给UI进程。通过bindServiceAsUser()绑定InCallService触发UI进程启动。InCallPresenterDialer应用进程MVP模式中的Presenter接收InCallService的Call状态更新控制InCallActivity的创建/销毁。管理子Presenter如CallCardPresenter和界面逻辑。通过InCallAdapter将用户操作接听/挂断转发给CallsManager。InCallActivityDialer应用进程界面容器承载通话UI的Activity动态加载Fragment如CallCardFragment。仅响应界面事件业务逻辑委托给InCallPresenter。布局仅为FrameLayout具体UI由Fragment实现。
二、核心交互流程以去电MO为例 Call创建与状态同步 CallsManager创建Call对象触发onCallAdded回调。InCallController监听到事件绑定InCallService服务跨进程。绑定成功后InCallServiceImpl通知InCallPresenter启动InCallActivity。 界面启动与用户操作 InCallPresenter调用startActivity()启动InCallActivity加载通话UI。用户点击“拨号”后InCallPresenter通过InCallAdapter调用CallsManager.placeOutgoingCall()。 底层通话建立 CallsManager通过ConnectionService与Modem交互Call状态变为DIALING→ACTIVE。状态变化经InCallController同步至UI进程触发InCallPresenter更新界面如显示通话计时。 #mermaid-svg-xJpZsep0Ovol4Aec {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-xJpZsep0Ovol4Aec .error-icon{fill:#552222;}#mermaid-svg-xJpZsep0Ovol4Aec .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xJpZsep0Ovol4Aec .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-xJpZsep0Ovol4Aec .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xJpZsep0Ovol4Aec .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xJpZsep0Ovol4Aec .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xJpZsep0Ovol4Aec .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xJpZsep0Ovol4Aec .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xJpZsep0Ovol4Aec .marker.cross{stroke:#333333;}#mermaid-svg-xJpZsep0Ovol4Aec svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xJpZsep0Ovol4Aec .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xJpZsep0Ovol4Aec text.actortspan{fill:black;stroke:none;}#mermaid-svg-xJpZsep0Ovol4Aec .actor-line{stroke:grey;}#mermaid-svg-xJpZsep0Ovol4Aec .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-xJpZsep0Ovol4Aec .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-xJpZsep0Ovol4Aec #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-xJpZsep0Ovol4Aec .sequenceNumber{fill:white;}#mermaid-svg-xJpZsep0Ovol4Aec #sequencenumber{fill:#333;}#mermaid-svg-xJpZsep0Ovol4Aec #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-xJpZsep0Ovol4Aec .messageText{fill:#333;stroke:#333;}#mermaid-svg-xJpZsep0Ovol4Aec .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xJpZsep0Ovol4Aec .labelText,#mermaid-svg-xJpZsep0Ovol4Aec .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-xJpZsep0Ovol4Aec .loopText,#mermaid-svg-xJpZsep0Ovol4Aec .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-xJpZsep0Ovol4Aec .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-xJpZsep0Ovol4Aec .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-xJpZsep0Ovol4Aec .noteText,#mermaid-svg-xJpZsep0Ovol4Aec .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-xJpZsep0Ovol4Aec .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xJpZsep0Ovol4Aec .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xJpZsep0Ovol4Aec .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xJpZsep0Ovol4Aec .actorPopupMenu{position:absolute;}#mermaid-svg-xJpZsep0Ovol4Aec .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-xJpZsep0Ovol4Aec .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xJpZsep0Ovol4Aec .actor-man circle,#mermaid-svg-xJpZsep0Ovol4Aec line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-xJpZsep0Ovol4Aec :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户操作 InCallActivity InCallPresenter InCallAdapter CallsManager InCallController InCallService 点击拨号 onUserAction(拨号) placeOutgoingCall() placeOutgoingCall() 更新Call状态 onCallAdded(Call) addCall(ParcelableCall) onCallAdded() 刷新界面(计时/状态) 用户操作 InCallActivity InCallPresenter InCallAdapter CallsManager InCallController InCallService 三、与Call对象的交互关系 Call的生命周期管理 创建CallsManager在去电/来电时创建Call对象分配唯一ID。状态流转Call状态DIALING、RINGING、ACTIVE等由CallsManager驱动通过setCallState()更新。销毁通话结束时CallsManager移除Call并触发onCallRemoved。 Call数据的跨进程传递 InCallController将Call转换为ParcelableCall可序列化对象通过Binder传递至UI进程。InCallPresenter解析ParcelableCall更新界面元素如联系人姓名、通话时长。 用户操作与Call状态联动 接听/挂断等操作通过InCallAdapter回调至CallsManager后者调用Call.answer()或Call.disconnect()。状态变化反向同步至UI形成闭环例如挂断后界面关闭。
四、设计特点与架构价值 分层解耦 上层UI层InCallActivity仅负责渲染InCallPresenter处理逻辑符合MVP模式。下层服务层CallsManager专注状态机InCallController处理跨进程通信。 跨进程高效同步 通过Binder机制实现Telecom进程与Dialer进程的实时状态同步ParcelableCall序列化。 可扩展性 CallsManager的监听器模式支持动态添加组件如Ringer振铃模块、CallAudioManager音频控制。InCallPresenter可管理多类子Presenter适应不同通话场景如视频通话、会议。
五、链路
这一架构通过状态驱动CallsManager与界面逻辑分离MVP模式实现高内聚低耦合
核心链路CallsManager → InCallController → InCallPresenter → InCallActivity 构成状态传递闭环交互本质Call对象作为载体在进程间传递状态驱动UI与底层服务协同。 其设计充分体现了Android系统服务的模块化思想为通话功能提供了稳定可扩展的基础。
六、Call 状态
1. DIALING拨号中
定义用户发起呼叫后系统开始连接对方但尚未接通的阶段。触发时机 用户拨号后立即进入此状态无论是否开始响铃。若需选择通话账户如VoIP或SIM卡会先进入SELECT_PHONE_ACCOUNT状态确认后转为DIALING。 行为特征 主叫方听回铃音或等待提示音被叫方设备未响铃。若拨号失败如无信号会转为DISCONNECTED连接断开。
2. RINGING响铃中
定义被叫方收到来电请求设备开始响铃或震动的状态。触发时机 主叫方拨号后被叫方网络收到呼叫请求时触发。若被叫方正在通话中此状态可能伴随CALL_WAITING呼叫等待提示。 行为特征 被叫方设备响铃显示来电界面。主叫方仍处于DIALING状态直至被叫方接听。
3. ACTIVE通话中
定义双方已建立连接可实时双向通话。触发时机 被叫方接听来电后主被叫双方均进入此状态。从HOLDING通话保持状态恢复时也会切换至此。 行为特征 通话计时器启动界面显示通话时长。支持操作如静音MUTE、保持HOLD、多方通话等。
4. HOLDING保持中
通话被主动暂停如接听新来电双方暂时中断语音连接。界面显示“已保持”恢复后回到ACTIVE。
5. DISCONNECTING断开中
用户挂断电话后系统释放资源的中间状态随后转为DISCONNECTED。
6. DISCONNECTED已断开
通话完全结束资源已释放。界面显示挂断提示如通话时长总结。
7. CALL_WAITING呼叫等待
用户通话中时第三方来电当前通话保持新来电进入RINGING状态。
状态转换关系
通话状态的典型生命周期流程如下 #mermaid-svg-EVNxjb2q9WrpzxCJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .error-icon{fill:#552222;}#mermaid-svg-EVNxjb2q9WrpzxCJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EVNxjb2q9WrpzxCJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .marker.cross{stroke:#333333;}#mermaid-svg-EVNxjb2q9WrpzxCJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .cluster-label text{fill:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .cluster-label span{color:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .label text,#mermaid-svg-EVNxjb2q9WrpzxCJ span{fill:#333;color:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .node rect,#mermaid-svg-EVNxjb2q9WrpzxCJ .node circle,#mermaid-svg-EVNxjb2q9WrpzxCJ .node ellipse,#mermaid-svg-EVNxjb2q9WrpzxCJ .node polygon,#mermaid-svg-EVNxjb2q9WrpzxCJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .node .label{text-align:center;}#mermaid-svg-EVNxjb2q9WrpzxCJ .node.clickable{cursor:pointer;}#mermaid-svg-EVNxjb2q9WrpzxCJ .arrowheadPath{fill:#333333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-EVNxjb2q9WrpzxCJ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-EVNxjb2q9WrpzxCJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EVNxjb2q9WrpzxCJ .cluster text{fill:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ .cluster span{color:#333;}#mermaid-svg-EVNxjb2q9WrpzxCJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EVNxjb2q9WrpzxCJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 被叫方响应 被叫方接听 用户点击保持 恢复通话 挂断 DIALING RINGING ACTIVE HOLDING DISCONNECTING DISCONNECTED 特殊场景 通话保持时新来电ACTIVE → HOLDING原通话 RINGING新来电。拨号失败DIALING → DISCONNECTED。
各个层的差异
DriverCall.StateCall.State(opt/telephony)Connection.State(base/telecomm)CallState(services/Telecomm)Call.State(base/telecomm)Call.State(Dialler)ACTIVEACTIVESTATE_ACTIVEACTIVESTATE_ACTIVEACTIVEHOLDINGHOLDINGSTATE_HOLDINGON_HOLDSTATE_HOLDINGONHOLDDIALINGDIALINGSTATE_DIALINGDIALINGSTATE_DIALINGDIALINGALERTINGALERTINGRINGALERTINGINCOMINGINCOMINGSTATE_RINGINGRINGINGSTATE_RINGINGINCOMINGWAITINGWAITINGCALL_WAITINGIDLEIDLEDISCONNECTEDSTATE_DISCONNECTEDDISCONNECTEDSTATE_DISCONNECTEDDISCONNECTEDDISCONNECTINGDISCONNECTINGSTATE_DISCONNECTINGDISCONNECTINGSTATE_INITIALIZINGCONNECTINGSTATE_CONNECTINGCONNECTINGSTATE_NEWNEWSTATE_NEWSTATE_PULLING_CALLSTATE_PULLING_CALLSELECT_PHONE_ACCOUNTSTATE_SELECT_PHONE_ACCOUNTSELECT_PHONE_ACCOUNTABORTEDSTATE_DISCONNECTEDDISCONNECTEDSTATE_PRE_DIAL_WAITINVALIDCONFERENCEDBLOCKEDWAIT_ACCOUNT_RESPONSE
七、MT 与 MO
在Android通话系统中MOMobile Originated移动始发和MTMobile Terminated移动终止 分别指代用户主动拨打电话主叫和接听来电被叫的流程。
1. MO去电流程
定义用户主动发起呼叫的过程即“拨打电话”。 核心步骤
拨号触发用户在Dialer应用的拨号界面DialpadFragment点击拨号按钮通过Intent.ACTION_CALL发起请求。权限检查 系统检查CALL_PHONE权限及默认拨号器身份TelecomUtil.hasCallPhonePermission()。紧急呼叫如ACTION_CALL_EMERGENCY绕过权限限制。 Telecom服务处理 TelecomServiceImpl.placeCall()验证号码合法性并通过CallsManager创建通话对象Call。 UI启动与状态更新 系统启动InCallActivity根据通话状态如DIALING显示拨号界面。底层Modem返回DIALING状态后界面更新为拨号中。 呼叫建立 被叫方接听后状态转为ACTIVE通话计时开始。
流程图简化 2. MT来电流程
定义用户接收来电并接听的过程即“接听电话”。 核心步骤
来电通知 Modem检测到来电通过RIL层上报RINGING状态至CallsManager。 铃声与震动 CallNotifier调用Ringer播放铃声非DIALING状态独有。 UI启动 系统启动InCallActivity显示来电界面如联系人信息、接听/挂断按钮。 用户响应 接听状态转为ACTIVE建立双向通话。拒接状态转为DISCONNECTED。
流程图简化 #mermaid-svg-nY5SoumCKKZIwtpo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .error-icon{fill:#552222;}#mermaid-svg-nY5SoumCKKZIwtpo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nY5SoumCKKZIwtpo .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-nY5SoumCKKZIwtpo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nY5SoumCKKZIwtpo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nY5SoumCKKZIwtpo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nY5SoumCKKZIwtpo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nY5SoumCKKZIwtpo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nY5SoumCKKZIwtpo .marker.cross{stroke:#333333;}#mermaid-svg-nY5SoumCKKZIwtpo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nY5SoumCKKZIwtpo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .cluster-label text{fill:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .cluster-label span{color:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .label text,#mermaid-svg-nY5SoumCKKZIwtpo span{fill:#333;color:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .node rect,#mermaid-svg-nY5SoumCKKZIwtpo .node circle,#mermaid-svg-nY5SoumCKKZIwtpo .node ellipse,#mermaid-svg-nY5SoumCKKZIwtpo .node polygon,#mermaid-svg-nY5SoumCKKZIwtpo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nY5SoumCKKZIwtpo .node .label{text-align:center;}#mermaid-svg-nY5SoumCKKZIwtpo .node.clickable{cursor:pointer;}#mermaid-svg-nY5SoumCKKZIwtpo .arrowheadPath{fill:#333333;}#mermaid-svg-nY5SoumCKKZIwtpo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nY5SoumCKKZIwtpo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nY5SoumCKKZIwtpo .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-nY5SoumCKKZIwtpo .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-nY5SoumCKKZIwtpo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nY5SoumCKKZIwtpo .cluster text{fill:#333;}#mermaid-svg-nY5SoumCKKZIwtpo .cluster span{color:#333;}#mermaid-svg-nY5SoumCKKZIwtpo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nY5SoumCKKZIwtpo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接听 拒接 Modem上报来电 Ringer播放铃声 启动InCallActivity 显示RINGING界面 用户操作 ACTIVE状态 DISCONNECTED 3. MO与MT的核心区别
维度MO主叫MT被叫触发起点用户主动拨号网络侧下发来电请求关键状态DIALING拨号中RINGING响铃中系统组件DialpadFragment触发IntentRIL/CallsManager检测来电状态特殊处理紧急呼叫权限绕过铃声播放RingerVoLTE角色主叫UE构造SIP INVITE被叫S-CSCF触发业务逻辑如彩铃
注意点
MO用户拨号 → 权限检查 → Telecom处理 → 界面显示DIALING → 通话建立ACTIVE。MT网络下发来电 → 播放铃声 → 界面显示RINGING → 用户接听ACTIVE或拒接DISCONNECTED。 本质差异在于触发源用户主动 vs. 网络被动和核心状态DIALING vs. RINGING。理解两者区别对开发通话功能、优化用户体验及设计测试用例至关重要。