【安卓深度控件開發(1.4)】Creating Custom Views (官方示例文檔漢化版)(4)

<h2>視圖的優化</h2> <p>您如今有一個精心設計的視圖,響應手勢和平滑過渡,如今須要確保視圖流暢。爲了不一個 UI 在播放過程當中感受緩慢或斷斷續續,您必須確保您的動畫始終運行在每秒 60 幀。</p> <p>&#160;</p> <h3>少許的頻繁處理</h3> <p>爲了加快您的視圖,在 <a href="http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)" target="_blank">onDraw()</a> 中消除沒必要要的被頻繁調用的例程代碼,這將給你最大的回報。特別是在 <a href="http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)" target="_blank">onDraw()</a> 中建立對象,由於這可能觸發形成緩慢的垃圾回收。在初始化期間或動畫之間分配對象。永遠不要在動畫運行時分配新對象。</p> <p>除了讓 <a href="http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)" target="_blank">onDraw()</a> 精簡以外,您還應該肯定儘量的減小被調用。多數 <a href="http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)" target="_blank">onDraw()</a> 調用由 <a href="http://developer.android.com/reference/android/view/View.html#invalidate()" target="_blank">invalidate()</a> 產生。因此應該排除沒必要要的 <a href="http://developer.android.com/reference/android/view/View.html#invalidate()" target="_blank">invalidate()</a> 調用。在可能的狀況下,調用帶有四個參數版本的 <a href="http://developer.android.com/reference/android/view/View.html#invalidate()" target="_blank">invalidate()</a> 而非無參數的版本。無參數的版本使整個視圖無效,而四個參數的版本只會使視圖的特定區域無效。此方法容許繪製要求可更有效並能夠消除在無效矩形區域以外的區域。</p> <p>另外一個很是低效的操做是遍歷佈局。當一個視圖調用 <a href="http://developer.android.com/reference/android/view/View.html#requestLayout()" target="_blank">requestLayout()</a> , Android UI 系統必須遍歷整個視圖樹來肯定每一個視圖的大小。若是它發現有衝突的測量,它可能須要屢次遍歷層次結構。UI 設計師有時爲了獲得應有的行爲建立深層嵌套的 <a href="http://developer.android.com/reference/android/view/ViewGroup.html" target="_blank">ViewGroup</a> 層次結構。這些深視圖層次結構會致使性能問題。使您的視圖層次結構儘量淺。</p> <p>若是您有一個複雜的用戶界面,您應考慮編寫自定義 <a href="http://developer.android.com/reference/android/view/ViewGroup.html" target="_blank">ViewGroup</a>,以執行其佈局。不像內建的視圖,您的自定義視圖能夠作出特定於應用程序的子級大小和形狀,假設,從而避免遍歷其子級來計算測量。<font color="#006600">PieChart</font> 示例演示如何擴展視圖分組做爲自定義視圖的一部分。<font color="#006600">PieChart</font> 有子視圖,但它永遠不會衡量他們。相反,它將根據本身的自定義佈局算法直接設置其大小。</p> <p>&#160;</p> <h3>使用硬件加速</h3> <p>從 Android 3.0 開始, Android 2D 圖形系統支持使用大多數新的 Android 設備上使用硬件 GPU(圖形處理單元) 加速。對於不少應用程序來講, GPU 硬件加速可能致使巨大的性能提高,但它並非每一個應用程序的正確選擇。Android 框架提供精細控制您的應用程序的哪些部分是或不是硬件加速的能力。</p> <p>查看 Android 開發手冊中的<a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html" target="_blank">硬件加速</a>瞭解如何在應用程序,活動或窗口級別啓用硬件加速。請注意除了開發人員指南中的說明,您還必須經過在 <font color="#006600">AndroidManifest.xml</font> 中指定 <font color="#006600">&lt;uses-sdk android:targetSdkVersion=&quot;11&quot;/&gt;</font> 設置目標應用程序的 API 爲 11 或更高。</p> <p>一旦您啓用了硬件加速,你可能不會看到增長性能。移動 GPU 都很是擅長某些任務如縮放、 旋轉以及處理位圖圖像。但可能不太擅長繪製線條與曲線這類的任務。要得到最大的 GPU 加速,您應該最大化 GPU 擅長的任務,減小它不擅長的任務。</p> <p>在 <font color="#006600">PieChart</font> 中,例如,繪製餅圖是相對較慢的。每次旋轉時重繪致使 UI 緩慢。解決方案是將餅圖放置在一個子 <a href="http://developer.android.com/reference/android/view/View.html" target="_blank">View</a> 中並設置 <a href="http://developer.android.com/reference/android/view/View.html" target="_blank">View</a> 的<a href="http://developer.android.com/reference/android/view/View.html#setLayerType(int, android.graphics.Paint)" target="_blank">圖層類型</a>爲 <a href="http://developer.android.com/reference/android/view/View.html#LAYER_TYPE_HARDWARE">LAYER_TYPE_HARDWARE</a>。那麼 GPU 可能將它緩存爲靜態圖像。這個示例定義了一個 PieChart 的內部類,以最小化代碼量更改來實現這一解決方案。</p> <div style="border-bottom: #ddd 1px solid; border-left: #ddd 1px solid; padding-bottom: 1em; margin: 0px 0px 1em; padding-left: 1em; padding-right: 1em; background: #f7f7f7; overflow: auto; border-top: #ddd 1px solid; border-right: #ddd 1px solid; padding-top: 1em"> <pre> <span style="color: #0000ff">private</span> <span style="color: #0000ff">class</span> PieView <span style="color: #0000ff">extends</span> View {html

<span style="color: #0000ff">public</span> PieView(Context context) {
       <span style="color: #0000ff">super</span>(context);
       <span style="color: #0000ff">if</span> (!isInEditMode()) {
           setLayerType(View.LAYER_TYPE_HARDWARE, <span style="color: #0000ff">null</span>);
       }
   }
   
   @Override
   <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> onDraw(Canvas canvas) {
       <span style="color: #0000ff">super</span>.onDraw(canvas);

       <span style="color: #0000ff">for</span> (Item it : mData) {
           mPiePaint.setShader(it.mShader);
           canvas.drawArc(mBounds,
                   360 - it.mEndAngle,
                   it.mEndAngle - it.mStartAngle,
                   <span style="color: #0000ff">true</span>, mPiePaint);
       }
   }

   @Override
   <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> onSizeChanged(<span style="color: #0000ff">int</span> w, <span style="color: #0000ff">int</span> h, <span style="color: #0000ff">int</span> oldw, <span style="color: #0000ff">int</span> oldh) {
       mBounds = <span style="color: #0000ff">new</span> RectF(0, 0, w, h);
   }

   RectF mBounds;

}</pre>android

</div>算法

<br />canvas

<p>完成這一更改後,<font color="#006600">PieChart.PieView.onDraw()</font> 方法只在第一次顯示時調用。在其他的應用程序的生存期,餅圖是做爲圖像緩存由 GPU 在不一樣旋轉角度重繪。GPU 硬件是特別擅長這種事情,並當即產生明顯的性能差別。</p>緩存

<p>不過還有一種權衡。緩存圖像做爲硬件層消耗視頻內存,這是一種有限的資源。基於這個緣由,<font color="#006600">PieChart.PieView</font> 的最終版本只有當用戶對其滾動時將圖層類型設置爲 <a href="http://developer.android.com/reference/android/view/View.html#LAYER_TYPE_NONE" target="_blank">LAYER_TYPE_HARDWARE</a> 。在其餘狀況下,它設置其圖層類型爲 LAYER_TYPE_NONE,它容許 GPU 中止緩存圖像。</p>框架

<p>最後,不要忘記來分析您的代碼。一個改善視圖性能的技術可能在另外一處使用時對性能形成負面影響。</p>ide

相關文章
相關標籤/搜索