2011-12-01 18 views
3

我目前正在編寫一款應該以滾動方式顯示實時測量曲線的應用程序(想想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毫秒。
  • 繪圖本身使用畫布,並且性能足以跟上傳入的數據。

那麼久解釋之後,這裏的問題:

  1. 什麼是調用的Android /視圖/ ViewRoot.handleMessage? (每850毫秒的呼叫間隔相對相等,並且沒有明顯的鏈接(沒有直接呼叫,呼叫數量和相對位置未鏈接到用於繪製的消息處理程序)到我的活動的任何活動)
  2. 如何抑制對android/view/ViewRoot.handleMessage的調用,或者如何讓它們更快(我的LinearLayout中只有2個元素)
  3. 調用未使用的佈局首先讓我想起了狀態欄或一些隱藏的活動(例如,home屏幕),其可以使用這種佈局。但是,這些電話怎麼是我活動痕跡的一部分呢?據我瞭解,跟蹤只應追蹤活動進程。例如生成實時數據的服務調用不是跟蹤的一部分。
  4. 有沒有可能跟蹤對某些系統組件的個別調用?當我在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()
  5. 偏題:是否有可能導出traceview(parent-children-CPU時間等)內顯示的數據,而不是截圖?

回答

5

好的,我找到了長期致電android/view/ViewRoot.handleMessage的原因。 這確實是由我的應用程序引起的。

我的應用程序有2個屏幕(活動),一個具有複雜的狀態信息佈局,另一個實時顯示傳入數據。

通過藍牙發送的數據包含混合的實時數據和狀態數據。當我切換到實時活動時,在開始新的實時活動後,我正在使用finish();停止狀態活動。不幸的是,這還不足以阻止消息處理程序,它在UI線程中接收新的狀態信息,並繼續更新不可見和已完成的活動中的狀態數據。此活動的重新發布導致了實時數據的結局。

現在解決了。顯示滾動現在合理平滑。

感謝您的耐心等待。對於任何在stackoverflow上絆倒這個線程的人來說,這可能是有用的。

jepo