android性能優化練習:過度繪制


練習:https://github.com/zhangbz/AndroidUIPorblems

查看過度繪制

在開發者選項中開啟"調試GPU過度繪制"

判斷標准

無色:沒有過度繪制,即只繪制了一次

藍色:一倍過度繪制

綠色:二倍過度繪制

淡紅色:三倍過度繪制

紅色:四倍或以上過度繪制

實踐

其中"This is test"四次或以上倍數過度繪制,其背景三倍,按鈕兩倍,按鈕中的文字三倍,背景一倍.

Mainactivity優化

首先分析布局文件,發現嵌套的LinearLayout設置了與父LinearLaytout相同的背景色,故刪除其背景色設置,效果如下

然后由於Android自帶的一些主題,window會被默認添加一個純色的背景,因為這個Activity的界面的背景占滿了整個屏幕,所以我們可以去掉該activity的默認繪制,在mainactivity的onCreate()方法里面修改代碼。

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().setBackgroundDrawable(null);//新增代碼

        //...
    }

效果如下:

至此,消除了該頁面三倍及以上過度繪制.

overdrawview優化

 

原實現方法如下,由於onDraw()方法中繪制的圖形存在覆蓋現象,因而導致了過度繪制

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        mPaint.setColor(Color.GRAY);
        canvas.drawRect(0, 0, width, height, mPaint);

        mPaint.setColor(Color.CYAN);
        canvas.drawRect(0, height/4, width, height, mPaint);

        mPaint.setColor(Color.DKGRAY);
        canvas.drawRect(0, height/3, width, height, mPaint);

        mPaint.setColor(Color.LTGRAY);
        canvas.drawRect(0, height/2, width, height, mPaint);
    }

修改代碼,避免相互覆蓋

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        mPaint.setColor(Color.GRAY);
        canvas.drawRect(0, 0, width, height/4, mPaint);

        mPaint.setColor(Color.CYAN);
        canvas.drawRect(0, height/4, width, height/3, mPaint);

        mPaint.setColor(Color.DKGRAY);
        canvas.drawRect(0, height/3, width, height/2, mPaint);

        mPaint.setColor(Color.LTGRAY);
        canvas.drawRect(0, height/2, width, height, mPaint);
    }

優化效果

busyondraw優化

點擊按鈕時會出現明顯的卡頓現象,從以下代碼中可以判斷,造成該問題的原因應該是onDraw()方法中的耗時操作

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (int i = 0; i < 1000; i++) {
            System.out.println("canvas = [" + canvas + "]" + i);
        }

        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(4);
        int radius = Math.min(getWidth(), getHeight()) / 2;
        canvas.drawCircle(getWidth()/2, getHeight()/2, radius, paint);
    }

優化方案:將耗時操作移入到子線程中

  new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("canvas = [" + canvas + "]" + i);
                }
            }
        }).start();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM