1. 程式人生 > >Android中InCallUI顯示太慢問題分析

Android中InCallUI顯示太慢問題分析

完整分析流程和詳細內容也可以下載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 = [email protected]

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 = [email protected]

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.

#201407101558


相關推薦

AndroidInCallUI顯示問題分析

完整分析流程和詳細內容也可以下載PDF文件:一、問題現象當手機有來電時,先聽到鈴聲,過了比較長的一段時間(3-4s)螢幕才點亮並顯示來電介面。Platform:MT6581Android版本:4.4KK

解決Android SDK Manager下載問題

出現 ges com image nag 完成 nbsp log androi 1.打開 Android SDK Manager 2.Tools----->Options 完成之後重啟 如下 很快就出現以下內容 解決Android

android倒計時控件CountDownTimer分析

構造方法 stat 一個 情況 onfinish future 控件 pre 計算 android中倒計時控件CountDownTimer分析 1 示例代碼 new CountDownTimer(10000, 1000) { public void onTic

RN navigation 的tabar在Android背景顯示成藍色

使用TabNavigator的時候,在iOS上顯示正常,但是在Android中顯示的有問題,如下圖,背景成了藍色了。 經過檢視官網文件。明白了少寫了一個屬性。tabBarComponent:TabBarBottom, 字面理解就是tabbar元件,注意這是一個元件,需要匯入,但是iOS

android studio 匯入專案

今天從github上下載了一個專案, 發現匯入Android studio的時候 發現好慢。 找了下解決辦法,自己留個記錄 原因: 下載的專案和你當前已經下載的grandle 不一致, 導致匯入的時候到網上下載相應的版本。 坑爹吧。。。我能不能連上google的伺服器還難說呢。 讓我去

String.format的一些用法和Androiddouble顯示成科學計數的問題

本文轉載於 String.format()方法使用說明 http://blog.csdn.net/thc1987/article/details/17528093 和JAVA字串格式化-String.format()的使用 http://blog.csdn.net/lone

java的String.format的一些用法和Androiddouble顯示成科學計數的問題

本文轉載於 String.format()方法使用說明http://blog.csdn.net/thc1987/article/details/17528093 和JAVA字串格式化-String.format()的使用 http://blog.csdn.net

androidstagefright和OMXCodec原理分析

1. 框架結構 1.1StageFright和openCore和NuPlayer的關係 上圖可知,stagefright是在MediaPlayerService這一層加入的,和opencZ喎�"/kf/ware/vc/" target="_blank" class=

android WebView 顯示不全的問題

在開發過程中我的WebView只要加上 RunJavaScript jsi = new RunJavaScript(); // RunJavaScript為自己定義的內類,負責讓js呼叫。 detailsWebview.addJavascriptInterface(jsi,

androidPicasso顯示網路圖片

使用之前匯入jar包(picasso.jar網上搜搜都有)或者在android studio中新增依賴compile 'com.squareup.picasso:picasso:2.5.2' 使用方式

AndroidWebView顯示flash閃白屏解決方案

播放flash(.swf格式)檔案通常有兩種方式:SWF播放器,WebView,以下僅討論WebView播放flash的情況: 使用場景:需要對UI做定製,明顯,自己寫個flash播放器工作量太大,WebView輕巧多了。步驟如下: 1.安裝Adobe的flash外掛

AndroidPopupWindow顯示在指定位置

Android中PopupWindow位置的確定一般通過showAsDropDown函式來實現,該函式有兩個過載函式,分別定義如下: public void showAsDropDown(View anchor) { showAsDropDown(anchor, 0

AndroidToast顯示時間的自定義

Android中Toast的顯示時間為特定時間且不可更改,但是有時候我們開發設計需要讓Toast顯示更長時間,或者自己完全控制Toast的顯示和關閉。通過檢視Toast類的原始碼,可以看出,這有點難為它了,Toast類本身並沒有提供相應方法。 但是通過原始碼的檢視,還是可以看出點眉頭。原始碼分析思路

androidWebView 顯示不全的問題

android中WebView 顯示不全的問題 在開發過程中我的WebView只要加上RunJavaScript jsi = new RunJavaScript(); // RunJavaScript為自己定義的內類,負責讓js呼叫。 detailsWebview.ad

AndroidGC機制的相關分析

前言 我們知道在Android開發中,由於有垃圾回收機制,所以我們不用花費太多的心思在記憶體分配或釋放上,但是這不是說我們要完全忽略。我們知道系統分配給每個應用程式的記憶體是有限的,這個記憶體的上限叫做“堆大小”(Heap Size),不同的手機,所分配的大小

AndroidToast顯示時間的自定義控制

@SuppressLint("InflateParams") public static void show(Context context, String text) { View view = LayoutInflater.from(cont

深入淺出Android的App啟動流程分析

App啟動是指使用者點選手機桌面的app對應的icon開始,所以我們需要明白幾點基礎知識: 1.桌面也是一個Activity叫Launcher.java 2.在桌面點選icon啟動app跟在app內部啟動另一個Activity是一樣的都是呼叫startAct

Coredump介紹及如何在Android開啟和使用來分析Crash等問題

文章目錄:Coredump簡介及使用... 1目錄... 2一、什麼是Coredump. 3二、Coredump產生的原因... 3三、如何控制產生Coredump. 4四、使用Coredump的準備... 4五、開始使用Coredump. 5一、什麼是Coredump有些C/C++程式或者通過JNI呼叫了C

Android 圖片顯示的另一種方式 ImageSwitcher

    一般情況下,顯示圖片用ImageView,但在圖片解析度太小的情況下,用ImageView顯示圖片就會出問題,按照圖片本身大小顯示太小,看不清,自己規定大小尺寸,圖片顯示又太模糊,所以這種情況下用ImageSwitcher顯示圖片較佳,在自己規定大小尺寸的情況下,圖

Android 的dm-verity原理分析

Android 中的Verified Boot之dm-verity 之前做了一個Verified Boot模組相關的工作,但是在網上只有找到google的文件和一個nexus的patch。雖然有patch,但在不同版本的程式碼上實現起來卻可能有一些bug,所以特此記錄一下debug這個東西的過程