Android中InCallUI显示太慢问题分析

简介: 完整分析流程和详细内容也可以下载PDF文档:InCallUI_issue_analysis_report一、问题现象当手机有来电时,先听到铃声,过了比较长的一段时间(3-4s)屏幕才点亮并显示来电界面。


完整分析流程和详细内容也可以下载PDF文档:

一、问题现象

当手机有来电时,先听到铃声,过了比较长的一段时间(3-4s)屏幕才点亮并显示来电界面。

Platform:MT6581

Android版本:4.4KK

BuildType:userdebug

系统软件版本:SWC1E+UP

系统RAM:512M

二、Android4.4来电及IncallUI显示的流程

整个流程主要分为3个部分:

1、framework部分,其主要通过RIL与Modem进行通信,当有来电的时候Modem会通知RIL,RIL则将基础数据和信息进行解析和封装后继续向上通知,大概流程为:RIL->GsmCallTracker->GSMPhone->PhoneBase->CallManager,具体过程如下图:

2、TeleService部分,这部分是由android4.4之前的PhoneAPP改造而来的,其功能基本与之前的PhoneAPP相同,主要负责与framework层的telephony进行通信,并处理在应用层的与Phone相关的状态维护、功能实现和服务提供,其大概流程为:CallStateMonitor->CallNotifier->CallModeler->CallHandlerServiceProxy,具体过程如下图:

3、InCallUI部分,这部分是由android4.4之前的PhoneAPP中分离出来的,在源码目录结构中虽然独立了,但是最终编译完成之后却打包到了Dialer中,Dialer也是android4.4才有的,是由android4.4之前的Contacts中的Dalpad独立出来的,InCallUI的大概流程:CallHandlerService->CallList->Answerpresenter->InCallPresenter->CallButtonPresenter->CallCardPresenter->CallCardFragment,具体过程如下图:



三、问题分析

开机后不做任何操作的内存使用信息:

Log分析:

如下为在TeleService的CallNotifier部分的时间点及log信息,从07-09 19:28:41.883接收到来电消息到07-09 19:28:42.594消息解析分发给IncallUI的CallHandlerService结束,因为这个分发是异步单向的,所以不会同步阻塞:

07-09 19:28:41.883   896   896 D CallNotifier: RINGING... (new)

07-09 19:28:41.884   896   896 D CallNotifier: onNewRingingConnection(): state = RINGING, conn = { *  -> id: 1, num: 15026714486, MT: true, mDisconnected: false }

07-09 19:28:42.594   896   896 D CallNotifier: - onNewRingingConnection() done.

再看InCallUI的CallHandlerService部分的时间点和log信息,从07-09 19:28:42.583开始创建进程到07-09 19:28:43.396CallHandlerService - onCreate 再到07-09 19:28:43.655CallHandlerService正式收到InComingCall的消息:

07-09 19:28:42.583   666   866 I ActivityManager: Start proc com.android.incallui for service com.android.dialer/com.android.incallui.CallHandlerService: pid=4126 uid=10053 gids={50053, 3003, 1028, 1015, 3002}

07-09 19:28:43.396  4126  4126 I InCall  : CallHandlerService - onCreate

07-09 19:28:43.466   896   896 D CallHandlerServiceProxy: onIncoming: Call{mCallId=2, mState=INCOMING

07-09 19:28:43.655  4126  4138 I InCall  : CallHandlerService - onIncomingCall: Call{mCallId=2, mState=INCOMING

最后是InCallActivity部分的时间点和log信息,从07-09 19:28:44.144开始onCreate到07-09 19:28:46.869的onResume最终把界面显示出来给用户:

07-09 19:28:44.144  4126  4126 D InCall  : InCallActivity - onCreate()...  this = com.android.incallui.InCallActivity@41e225e0

07-09 19:28:46.869  4126  4126 I InCall  : InCallActivity - onResume()...

Systrace分析:

从systrace的图中可以看到,从incallui的进程起来到incallui的activityResume总共花了4.3s左右,其中启动进程花费804ms左右,具体如下图:


另外进程启动之后,从CallHandlerService的onCreate到ActivityStart的时间为540ms左右,具体如下图:

四、解决方案

通过以上分析我们发现每当来电时,整个过程中InCallUI接受TeleService的来电请求的环节最为耗时,因为需要启动InCallUI这个进程。另外Framework中的telephony以及TeleService都是系统中常驻的进程,不会被杀掉,所以响应速度非常快,TeleService进程常驻的相关设置:   

<application android:name="PhoneApp"

           android:persistent="true"

而InCallUI这个进程没有以上persistent的设置,所以在执行完通话的操作后会经常被系统LMK回收掉,鉴于以上原因,为了能够让InCallUI像TeleService一样响应的够快,我们给出了以下解决方案:

1、InCallUI不再独立为一个进程,将InCallUI与Dialer合并为一个进程

2、修改Dialer进程的属性,增加persistent=ture,使其常驻,进而实现InCallUI的常驻,缩短响应和加载出界面的时间

3、取消Dialer拨号时到InCallUI的过渡图片,因为Dialer和InCallUI同属一个进程后在执行拨号时的中间过渡(黑屏)时间被缩短,所以不再需要过渡图片,进而能够进一步提升性能和缩短加载InCallUI界面的时间

五、应用解决方案之后的对比分析

开机后不做任何操作的内存使用信息:

Dialer进程常驻之后开机会将它启动,Dialer进程所占内存信息如下:

Log分析:

如下为在TeleService的CallNotifier部分的时间点及log信息,从07-09 20:45:01.848接收到来电消息到07-09 20:45:03.959消息解析分发给IncallUI的CallHandlerService结束

07-09 20:45:01.848   900   900 D CallNotifier: RINGING... (new)

07-09 20:45:01.848   900   900 D CallNotifier: onNewRingingConnection(): state = RINGING,

07-09 20:45:03.959   900   900 D CallNotifier: - onNewRingingConnection() done.

再看InCallUI的CallHandlerService部分的时间点和log信息,从07-09 20:45:03.995CallHandlerService - onCreate07-09 20:45:04.229CallHandlerService正式收到InComingCall的消息,其中少了创建进程的步骤:

07-09 20:45:03.995   965   965 I InCall  : CallHandlerService - onCreate

07-09 20:45:04.190   900   900 D CallHandlerServiceProxy: onIncoming: Call{mCallId=3, mState=INCOMING

07-09 20:45:04.229   965   983 I InCall  : CallHandlerService - onIncomingCall: Call{mCallId=3, mState=INCOMING

最后是InCallActivity部分的时间点和log信息,从07-09 20:45:04.445开始onCreate到07-09 20:45:05.742的onResume最终把界面显示出来给用户:

07-09 20:45:04.445   965   965 D InCall  : InCallActivity - onCreate()...  this = com.android.incallui.InCallActivity@41e894c0

07-09 20:45:05.742   965   965 I InCall  : InCallActivity - onResume()...

Systrace分析:

因为没有了创建进程的过程,所以InCallUI的整个过程只有service的create到activity的resume,由上图可以看到用时1.809s左右。

六、结论

由以上的log分析、systrace分析以及应用解决方案之后的对比分析,我们可以发现不管是从用户的感觉还是实际的性能参数数据上看,整个过程的性能都得到了很大提升,时间上缩短了很多。另外虽然dialer进程常驻内存,但是其本身占用的内存比较少,基本上在10MB以下,所以对整个系统来讲影响比较小。


#analysed by jinshi.song from SWD2 Framework team.

#jinshi.song@jrdcom.com

#201407101558


目录
相关文章
|
数据处理 Android开发
关于安卓glide加载显示进度
安卓glide加载显示进度
340 0
|
2天前
|
安全 Android开发
Android 预置可卸载分区接收不到任何广播问题分析和解决
Android 预置可卸载分区接收不到任何广播问题分析和解决
13 0
|
Java Android开发 开发者
Android Studio Profiler Memory (内存分析工具)的简单使用及问题分析
Android Studio Profiler Memory (内存分析工具)的简单使用及问题分析
2569 0
Android Studio Profiler Memory (内存分析工具)的简单使用及问题分析
|
Android开发 C++
Android OpenGL显示任意3D模型文件
Android OpenGL显示任意3D模型文件
Android OpenGL显示任意3D模型文件
|
存储 缓存 Java
Android OpenGL 显示基本图形及相关概念解读
Android OpenGL 显示基本图形及相关概念解读
Android OpenGL 显示基本图形及相关概念解读
|
开发工具 Android开发
Android studio preview不显示
作为一个刚学习Android的小白,装Android studio的过程中就遇到了不少问题,这两天发现preview一直不显示,百度查了一下,很多教程都只是改了一下这里,但是治标不治本啊,新的项目又会出现这个问题。
224 0
Android studio preview不显示
|
XML 缓存 Android开发
Android Studio Dolphin | 2021.3.1不显示布局XML预览
Android Studio Dolphin | 2021.3.1不显示布局XML预览
1971 0
Android Studio Dolphin | 2021.3.1不显示布局XML预览
|
XML SQL 缓存
Android 音乐APP(四)显示专辑图片、本地数据库、自定义通知栏样式、通知栏显示
Android 音乐APP(四)显示专辑图片、本地数据库、自定义通知栏样式、通知栏显示
396 0
Android 音乐APP(四)显示专辑图片、本地数据库、自定义通知栏样式、通知栏显示
|
XML Android开发 数据格式
Android Glide加载网络图片不显示,但用网页打开又正常显示
Android Glide加载网络图片不显示,但用网页打开又正常显示
624 0
Android Glide加载网络图片不显示,但用网页打开又正常显示
|
XML 缓存 API
Android 天气APP(十四)修复UI显示异常、优化业务代码逻辑、增加详情天气显示
Android 天气APP(十四)修复UI显示异常、优化业务代码逻辑、增加详情天气显示
187 0
Android 天气APP(十四)修复UI显示异常、优化业务代码逻辑、增加详情天气显示