Android 5.0对Phone模块进行了重构,但在后续的使用中发现,MO发起过程中InCallActivity加载较慢,且在Qcom和MTK等芯片厂商加入双卡设置后,用户点击拨号按钮后需要等5s左右才能看到通话界面。在分析与解决该问题的过程中Google悄然发布了Android 5.1,其中对InCallActivity启动较慢的问题行了一些优化,下面对通话模块性能优化进行相应的分析和总结。
Android 5.0 中,Telephony Servic(原来的TeleService)部分功能被提取到了Telecom Service和Telecom Framework中。整个Telephony Phone模块包括了5个部分:InCallUI、Telecom Service、Telecom Framework、Telephony Service、Telephony Framework。其中新增的Telecom Framework被打包到framework.jar中,Telecom Service则打包到Telecom.apk里。
4.4和5.0 Telephony Phone模块对比(左边为4.4)
InCallActivity启动流程
因无论是MO还是MT,InCallActivity的启动流程类似,这里仅以MO为例。在Android 5.1 中InCallActivity 的启动有些许改动,但整体上与Android 5.0保持一致,整个InCallActivity的启动时序如下图所示 ( 以MO为例 ):
查看上图后可以知道,Android 5.1 中InCallActivity启动分析主要包括以下关键步骤:
1. 构造Dialing Intent
主要包括从Dialer的DialpadFragment的onClick方法开始,到Telecom Service的CallReceiver(PrimaryCallReceiver)的onReceive方法中。
- 启动InCallActivity
2.1 bind InCallService
并不是每次拨打电话都会执行bind InCallService 的操作。如果当前正在通话中,此时拨打号码则不会再次执行bind InCallService的操作。对于Android 5.1来说,bind InCallService这里有一点改动。如果是OutgoingCall,在bind InCallService的intent中会新增两个Extra值,即TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS和TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,这两个Extra值在后续的CircularRevealActivity显示时会用到。
2.2 InCallServiceImpl新增onBind和onUnbind方法
Android 5.1中,InCallServiceImpl中新覆写了onBind和onUnbind方法,并在onBind方法中执行InCallPresenter的setUp以及启动CircularRevealActivity。
2.3 新增CircularRevealActivity用于提高OutgoingCall的响应
bind InCallService一旦成功,立刻启动CircularRevealActivity,该Activity实际上是一个背景。在Android 5.0中,如果bind InCallService成功后,还需要等待InCallActivity的加载,最后才能显示给用户,而此时会导致很长时间的界面凝滞。如用户点击拨号后,需要等大概2s左右才能看到InCallActivity的启动。因此在Android 5.1中为了提高OutgoingCall的响应速度,在bind成功后立刻启动一个带动画的背景Activity,之后等InCallActivity准备好后再显示即可,这样做的目的是为了提高用户响应。
- 显示动画
在CallCardFragment中,新增animateForNewOutgoingCall()方法用于执行OutgoingCall时CallCardFragment的动画。
从MO的整个流程上来说,从用户点击拨号按钮开始到通话界面呈现,主要包括以下步骤:用户发起拨号操作,启动InCallActivity ,最后 更新InCallActivity状态。虽然Android 5.1 相较于 Android 5.0属于小幅更新,但落实到代码中却有不少改动。如Android 5.0在Telecom Framework的ConnectionService.createConnection()方法中,通过mAdapter.handleCreateConnectionComplete()方法最终启动InCallActivity。而对于Android 5.1,在Telecom Service的 CallReceiver.processOutgoingCallIntent()方法中,通过getCallsManager().startOutgoingCall()方法最终启动InCallActivity。
InCallActivity启动时间统计
①. 点击拨号按钮,对应的方法是Dialer中DialpadFragment.onClick()方法;
②. Telecom Service处理拨号请求;</