我目前正在編寫一款應該以滾動方式顯示實時測量曲線的應用程序(想想ECG記錄器或示波器)。 UI-Thread中意外的系統調用會導致顯示停頓。意想不到的android系統調用可以平滑顯示滾動圖形的口吃
數據通過藍牙滾入。所有的工作都很好,並且顯示屏以平均26幀/秒的更新率順利滾動。但是,儘管如此,顯示屏仍然顯得十分笨拙。
我用traceview得到更多的見解,根據traceview的口吃結果是致電android/view/ViewRoot.handleMessage
,每次通話平均持續131毫秒。 如果我在追蹤視圖中進一步挖掘循環被燒燬android/view/ViewRoot.performTraversals
內。這些CPU週期中有92%主要用於遞歸調用android/view/View.measure
。
由於遞歸調用結構,從那裏變得複雜。但是我可以找到對LinearLayout,FrameLayout和RelativeLayout的onMeasure()方法的調用。每個Layout類型的onMeasure()方法消耗大約相同數量的CPU週期。這是非常奇怪的,因爲在我的活動中,我只使用一個簡單的LinearLayout和2個元素。 我只看到沒有理由說爲什麼一個LinearLayout有2個元素的重新佈局會執行對未使用的佈局的調用,並且需要高達131 ms才能做到這一點。
進一步信息:
- 平臺HTC渴望HD採用Android 2.3.1。
- 我使用一個處理程序在UI線程中執行繪圖。
- 佈局是一個簡單的帶有2個元素的LinearLayout:一個自定義視圖和一個textField。
- 狀態欄隱藏着
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
。 - 該繪圖是在每個新的數據塊上執行的,每50毫秒。
- 繪圖本身使用畫布,並且性能足以跟上傳入的數據。
那麼久解釋之後,這裏的問題:
- 什麼是調用的Android /視圖/ ViewRoot.handleMessage? (每850毫秒的呼叫間隔相對相等,並且沒有明顯的鏈接(沒有直接呼叫,呼叫數量和相對位置未鏈接到用於繪製的消息處理程序)到我的活動的任何活動)
- 如何抑制對android/view/ViewRoot.handleMessage的調用,或者如何讓它們更快(我的LinearLayout中只有2個元素)
- 調用未使用的佈局首先讓我想起了狀態欄或一些隱藏的活動(例如,home屏幕),其可以使用這種佈局。但是,這些電話怎麼是我活動痕跡的一部分呢?據我瞭解,跟蹤只應追蹤活動進程。例如生成實時數據的服務調用不是跟蹤的一部分。
- 有沒有可能跟蹤對某些系統組件的個別調用?當我在traceview中放大時,我看到這個調用序列:
toplevel -> android/os/Message.clearForRecycle() -> android/os/MessageQueue.nativePollOnce() -> android/os/SystemClock.uptimeMillis() -> com/htc/profileflag/ProfileConfig.getProfilePerformance() -> android/os/Handler.dispatchMessage() -> android/view/ViewRoot.performTraversals()
- 偏題:是否有可能導出traceview(parent-children-CPU時間等)內顯示的數據,而不是截圖?