前置文章:
《 Android 4.4 Kitkat Phone工作流程浅析(一)__概要和学习计划》《Android 4.4 Kitkat Phone工作流程浅析(二)__UI结构分析》
《Android 4.4 Kitkat Phone工作流程浅析(三)__MO(去电)流程分析》
《Android 4.4 Kitkat Phone工作流程浅析(四)__RILJ工作流程简析》
《Android 4.4 Kitkat Phone工作流程浅析(五)__MT(来电)流程分析》
《Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程》
《Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程》
《Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析》
《Android 4.4 Kitkat Phone工作流程浅析(九)__状态通知流程分析》
《Android 4.4 Kitkat Phone工作流程浅析(十)__"通话显示"查询流程》
《Android 4.4 Kitkat Phone工作流程浅析(十一)__PSensor工作流程浅析》
《Android 4.4 Kitkat Phone工作流程浅析(十二)__4.4小结与5.0概览》
概要
Google在2015年3月9日低调发布了Android 5.1,从官方博客的描述来看只是进行了小幅更新,如增加多SIM卡支持,HD Voice支持等。虽然Google对外声称只是稳定性和性能上的微调,但在查看Telephony Phone相关代码后,Android 5.1在这一块的动作还是很大的。就目前了解的情况来看,Telephony Phone相关的改动包括:
1. 移除com.android.incallui进程;也就是说incallui以后也是运行在com.android.dialer进程中。
2. Telecom Service运行在system_server进程中;
3. 在Telecom Service中,CallActivity和EmergencyActivity使用独立进程com.android.server.telecom:ui;
4. 新增CircularRevealActivity;当发起OutgoingCall时,会先启动一个默认背景为蓝色的Activity即CircularRevealActivity,该Activity的作用主要是显示背景,用以给用户带来响应快的错觉。因为InCallActivity的启动较为耗时,因此先启动该Activity以便给用户带来一些界面改变效果。
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处
在Android AOSP 5.0 中 Telephony Phone 进行了重构,但在后续的测试中发现,MO发起过程中InCallActivity的较慢,且在Qcom和MTK等厂商加入双卡设置后,InCallActivity的界面呈现时间很长,用户在点击拨号按钮后需要等5s左右才能看到通话界面。在分析与解决该问题的过程中Google悄然发布了Android 5.1,其中对InCallActivity启动较慢的问题进行了一些优化。本系列文章主要记录分析Android 5.1 中 InCallActivity启动相关,以及一些优化尝试。
整个分析大纲如图1所示:
图 1 InCallActivity启动分析大纲
InCallActivity启动流程
因无论是MO还是MT,InCallActivity的启动流程类似,这里仅以MO为例。在Android 5.1 中InCallActivity 的启动有些许改动,但整体上与Android 5.0保持一致,整个InCallActivity的启动时序如图2所示 ( 以MO为例 ):
图 2 Android 5.1 InCallActivity start process(MO)
查看上图后可以知道,Android 5.1 中InCallActivity启动流程主要包括以下关键步骤:
1. 构造Dialing Intent
主要包括从Dialer的DialpadFragment的onClick方法开始,到Telecom Service的CallReceiver的onReceive方法中。Android 5.1 与Android 5.0的主要区别在于,前者在CallActivity中,始终会通过广播的方式将Dialing Intent发送给CallReceiver。而后者则是通过代码回调实现。
2. 启动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左右(AOSP)才能看到InCallActivity的启动。因此在Android 5.1中为了提高OutgoingCall的响应速度,在bind成功后立刻启动一个带动画的背景Activity,之后等InCallActivity准备好后再显示即可,这样做的目的是为了提高用户响应。
3. 显示动画
在CallCardFragment中,新增animateForNewOutgoingCall()方法用于执行OutgoingCall时CallCardFragment的动画。为了更直观与Android 5.1 MO 启动InCallActivity的流程进行对比,大家可参考图3 Android 5.0 InCallActivity的启动时序图:
图 3 Android 5.0 InCallActivity start process(MO)
从MO的整个流程上来说,从用户点击拨号按钮开始到通话界面呈现,主要包括以下步骤:用户发起拨号操作,启动InCallActivity ,最后 更新InCallActivity状态。从图2和图3的时序图可以看出,虽然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启动时间统计
在前文了解InCallActivity启动流程的基础上,本节主要分析如何统计InCallActivity的启动时间。通过分析InCallActivity的启动时间,从而确定InCallActivity启动缓慢的原因,并最终找到相关优化方案,这正是本文的意图。
时间统计原理
对于InCallActivity的启动时间统计,想必大家一开始就能想到通过在onCreate和onResume中加入log,最后统计两个log的时间差,从而计算出InCallActivity的启动时间。单对InCallActivity来讲,这样做是可以简单统计出一个时间的,我把这个时间称之为“函数执行时间”,也就是程序在执行中,各个方法所消耗的时间。
对于开发人员来说,函数执行时间确实可以反映出一些问题,比如InCallActivity从onCreate到onResume总共消耗多少时间。同时,也可以在各个方法中插入log,这样可以大致定位出比较耗时的方法,从而分析并优化该方法,最终减少其执行时所消耗的时间。若为了罩住耗时方