Android高級開發-佈局渲染流程與優化

擴展知識

CPU(中央處理器)與GPU(圖像處理器)android

主要是設計目標不一樣,針對不一樣的應用場景。多緩存多分支,適用於複雜的邏輯運算,主要負責Measure,Layout,Record,Execute的計算操做。canvas

CPU擅長邏輯控制和通用類型數據運算。CPU的運算速度取決於請了多麼厲害的教授,教授處理複雜任務的能力高,但簡單重複的任務,仍是人多快。衆核少緩存,適用於結構單一的數據處理,主要負責Rasterization(柵格化)操做。緩存

GPU擅長大規模併發計算。GPU的運算速度取決於僱了多少小學生。 bash

綠色的是計算單元,橙紅色的是存儲單元,橙黃色的是控制單元。

屏幕上顯示的文字、圖像等,都是經過屏幕上的像素點顯示顏色來完成的。 併發

Resterization柵格化是繪製那些Button,Shape,Path,String,Bitmap等組件最基礎的操做。它把那些組件拆分到不一樣的像素上進行顯示。這是一個很費時的操做,GPU的引入就是爲了加快柵格化的操做。

CPU負責把UI組件計算成Polygons,Texture紋理,而後交給GPU進行柵格化渲染。 整個流程以下ide

FPS (Frames Per Second)每秒幀數 60FPS 用戶看的話以爲動做是連續的,至少是每秒10-12幀的速度,而想達到流暢的效果,至少須要每秒24幀。這也是爲何電影片源一般都是24幀的緣由。若是和手機交互,如觸摸和反饋,低於60FPS會感受卡頓,60FPS是最佳流暢度。

爲了保證用戶的視覺效果,因此Android系統每隔16ms(1000ms/60fps)發出VSYNC信號,觸發對UI渲染。佈局

若是渲染操做超過了16ms,那麼用戶在16ms * 2 看到的2幀畫面相同,感受界面卡頓,即丟幀現象。優化

卡頓分析(16ms主要作兩件事)

  1. 將UI對象轉換成Polygons,Texture紋理。(LayoutInflater將XML轉換成JAVA對象給CPU)
  2. CPU傳遞數據給GPU、GPU進行繪製。

佈局優化

  1. 減小布局元素的層級嵌套,刪除多餘佈局。或更改佈局組件。如使用ContraintLayout。(減小轉換對象的時間)
  2. 減小布局中的背景。(減小GPU重複繪製)
  3. 自定義View是否進行裁剪。(減小GPU重複繪製)
public class ClipView extends View {

    Card[] cards;
    Paint paint;

    ......

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Card card;
        Bitmap bitmap;
        for (int i = 0; i < cards.length - 1; i++) {
            card = cards[i];
            bitmap = BitmapFactory.decodeResource(getResources(), card.resId);
            canvas.drawBitmap(bitmap, card.x, 0, paint);
//            drawCards(canvas, bitmap, card.x, cards[i + 1].x);
        }

        card = cards[cards.length - 1];
        bitmap = BitmapFactory.decodeResource(getResources(), card.resId);
        canvas.drawBitmap(bitmap, card.x, 0, paint);
    }

    private void drawCards(Canvas canvas, Bitmap bitmap, int s, int e) {
        canvas.save();
        canvas.clipRect(s, 0, e, bitmap.getHeight());
        canvas.drawBitmap(bitmap, s, 0, paint);
        canvas.restore();
    }
}

複製代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">
    <com.outman.example.androidtest.clip.ClipView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#0000ff"
        android:layout_margin="10dp"/>
</LinearLayout>
複製代碼

參考 www.jianshu.com/p/26000db61…spa

相關文章
相關標籤/搜索