1. 程式人生 > >Android顯示系統之View與SurfaceView更新螢幕的區別

Android顯示系統之View與SurfaceView更新螢幕的區別

/********************************************************************************************
 * author:[email protected]大鐘                                                                                                                          
 * E-mail:[email protected]                                                                                                             
 * 

http://blog.csdn.net/conowen                                                                                                              
 * 注:本文為原創,僅作為學習交流使用,轉載請標明作者及出處。      

 ********************************************************************************************/


1、View

View

extends Object

implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource

Class Overview

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class forwidgets

, which are used to create interactive UI components (buttons, text fields, etc.). The subclass is the base class forlayouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.

View類為使用者介面提供了最基礎的元件,View類元件負責更換螢幕與處理事件。同時,View類也是widgets類的基礎類,widgets類可以建立基礎的UI元件,如Bottons、Textview等等。View類的其中一個直接子類ViewGroup是layous的基礎類,layous是用來裝載View或者其他的ViewGrous的,並且可以定義這些裝載內容的特性。



2、

          從上述的Overview可知,SurfaceView是繼承於View類的,(GLSurfaceView是繼承於SurfaceView的)。關於SurfaceView的詳細可以參看之前的博文

Android更新螢幕主要有兩種方式,繼承SurfaceView實現SurfaceHolder.callback介面來實現螢幕的更新。

或者直接繼承View類,複寫OnDraw方法實現更新螢幕。

事實上,兩種是用本質的區別的。

3、View與SurfaceView更新螢幕的區別

對於SurfaceView更新螢幕,是在非UI執行緒(主執行緒)中更新的。而對於View,則是在UI的主執行緒中更新畫面。
那在UI的主執行緒中更新畫面很容易造成主執行緒的堵塞,造成程式的長時間無響應,當主UI執行緒超過5秒鐘沒有響應使用者的操作,Android系統會提示是否關閉應用程式。


當使用SurfaceView 來更新畫面的話,就不必擔心堵塞主UI執行緒這個問題了。但是這也帶來了另外一個問題,執行緒的同步性。

所以當更新操作說花的時間較長,而且資料量較大的話,一般採用SurfaceView方式更新螢幕,而少用View。

4、Demo程式

/*
 * author: conowen
 * e-mail: [email protected]
 * date  :  2012.8.8
 */
package com.conowen.viewtestdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

public class MyView extends View {

	private int counter;

	public MyView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
/*		synchronized (this) {
			try {
				wait(10 * 1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
*/
		// 設定Canvas物件的背景顏色
		canvas.drawColor(Color.YELLOW - counter);

		// 建立畫筆
		Paint p = new Paint();
		// 設定畫筆顏色
		p.setColor(Color.RED);
		// 設定文字大小
		p.setTextSize(40);
		// 消除鋸齒
		p.setFlags(Paint.ANTI_ALIAS_FLAG);

		// 在canvas上繪製rect
		canvas.drawArc(new RectF(100, 50, 400, 350), 0, counter, true, p);
		if (counter == 400) {
			counter = 0;
		}

		canvas.drawText("counter = " + (counter++), 500, 200, p);
		// 重繪, 再一次執行onDraw 程式
		invalidate();

	}

}

效果圖:

開啟下面的程式碼,測試堵塞主UI執行緒(長按螢幕5秒以上)就會出現如下的圖。

synchronized (this) {
			try {
				wait(10 * 1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}




注意:

     onDraw方法是運行於主UI執行緒中的,如果你在onDraw中執行invalidate()方法去更新螢幕,是可以的。但是你既要繼承View而且要不希望堵塞主UI執行緒的話,可以另外新建執行緒,然後線上程中執行postInvalidate()方法去更新螢幕。也就是說invalidate()方法只能在主UI執行緒中被呼叫,postInvalidate()方法只能在非主UI執行緒中被呼叫。否則會出現如下error

08-08 15:33:34.587: E/AndroidRuntime(4995): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

這兩個方法只是再次呼叫onDraw方法而已

Invalidate the whole view. If the view is visible, will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call.

如下面的程式碼所示。這樣的話,就不必擔心主UI執行緒被堵塞了。

/*
 * author: conowen
 * e-mail: [email protected]
 * date  :  2012.8.4
 */
package com.conowen.viewtestdemo;

import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

public class MyView extends View {

    private int counter;
    private boolean isNewThread;
    private RectF rectf;
    private Paint p;
    private Timer timer;

    public MyView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        isNewThread = true;
        rectf = new RectF(100, 50, 400, 350);
        p = new Paint();
        timer = new Timer();
    }

    public void newThread() {

        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                postInvalidate();
                
            }
        }, 0, 100);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        if (isNewThread) {
            newThread();
            isNewThread = false;
        }
        // 設定Canvas物件的背景顏色
        canvas.drawColor(Color.YELLOW - counter);

        // 設定畫筆顏色
        p.setColor(Color.RED);
        // 設定文字大小
        p.setTextSize(40);
        // 消除鋸齒
        p.setFlags(Paint.ANTI_ALIAS_FLAG);

        // 在canvas上繪製rect
        canvas.drawArc(rectf, 0, counter, true, p);
        if (counter == 400) {
            counter = 0;
        }

        canvas.drawText("counter = " + (counter++), 500, 200, p);

    }

}




相關推薦

Android顯示系統ViewSurfaceView更新螢幕區別

/********************************************************************************************  * author:[email protected]大鐘        

Android圖形系統Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之間的聯絡

SurfaceHolder 結構 繼承關係 public interface SurfaceHolder android.view.SurfaceHolder  概述 抽象介面持有人顯示錶面。允許您控制面的大小和格式

Android 多媒體應用:視訊播放VideoViewSurfaceView

  實際上我們這裡所說的VideoView與SurfaceView並不適用於我們真正的實際開發中,那麼我們為什麼還要學習他們呢?在實際開發中我們又該如何使用什麼呢? 一、為什麼要學習VideoView與SurfaceView   在思考為什麼學習VideoV

Android開發】FragmentAcitvity通信

對象 p s ets roi mit blog () open findview   上一篇我們講到與Fragment有關的經常使用函數,既然Fragment被稱為是“小Activity”。如今我們來講一下Fragment怎樣與Acitivity通信。

MVC初級知識——ViewController的講解

str 寫入 開發 content login 結果 執行 母版 rect Controller是MVC中比較重要的一部分。幾乎所有的業務邏輯都是在這裏進行處理的,並且從Model中取出數據。在ASP.NET MVC Preview5中,將原來的Controlle

Android進階FragmentActivity之間的數據交互

|| int tails support 實例 onclick interface rod sel 1 為什麽 因為Fragment和Activity一樣是具有生命周期,不是一般的bean通過構造函數傳值,會造成異常。 2 Activity把值傳遞給Fragment 2.1

Android 7.0 拍照圖片裁剪適配

在Android 7.0以上,在相機拍照和圖片裁剪上,可能會碰到以下一些錯誤: Process: com.yuyh.imgsel, PID: 22995 // 錯誤1 android.os.FileUriExposedException: file:///storage/emulate

android Gui系統SurfaceFlinger(5)---Vsync(2)

9.Vsync第二部分 在上一篇中我們講到,檢視的重新整理需要很多步驟, void SurfaceFlinger::handleMessageRefresh() { ATRACE_CALL(); preComposition();  //合成前的準備 rebui

android Gui系統SurfaceFlinger(4)---Vsync(1)

8.Vsync 回到頂部 8.1概論 VSYNC(Vertical Synchronization)是一個相當古老的概念,對於遊戲玩家,它有一個更加大名鼎鼎的中文名字—-垂直同步。 “垂直同步(vsync)”指的是顯示卡的輸出幀數和螢幕的垂直重新整理率相同,這完全是一個CRT顯示器上

android Gui系統SurfaceFlinger(3)---SurfaceFlinger

7.SurfaceFlinger SurfaceFlinger在前面的篇幅了,多有涉及。 SurfaceFlinger是GUI重新整理UI的核心,所以任何關於SurfaceFlinger的改進都會對android UI系統有重大影響。 SurfaceFlinger主要分為4個部分 1

android Gui系統SurfaceFlinger(2)---BufferQueue

6 BufferQueue 上一篇已經說到,BufferQueue是SurfaceFlinger管理和消費surface的中介,我們就開始分析bufferqueue。 每個應用 可以由幾個BufferQueue? 應用繪製UI 所需的記憶體從何而來? 應用和SurfaceFlinge

android Gui系統SurfaceFlinger(1)---SurfaceFlinger概論

  GUI 是任何系統都很重要的一塊。 android GUI大體分為4大塊。 1)SurfaceFlinger 2)WMS 3)View機制 4)InputMethod 這塊內容非常之多,但是理解後,可以觸類旁通,其實現在主流的系統,包括andorid,ios

Linux檔案系統使用者組管理

目錄 ①使用者與組管理之重要檔案 (1)/etc/passwd (2)/etc/shadow (3)/etc/login.defs (4)/etc/skel (目錄) (5)/etc/de

Android學習筆記View的事件分發機制

一、點選事件的傳遞規則 所謂的點選事件分發過程,其實就是當我們點選螢幕,產生了一個MotionEvent之後,系統將這個事件傳遞給一個具體View的過程。總的來說,事件總是先傳遞給Activity,然後傳遞給Window,再傳遞給頂級View(Activity→Window

android Gui系統SurfaceFlinger(1)---SurfaceFlinger概論【轉】

轉自:https://www.cnblogs.com/deman/p/5584198.html 閱讀目錄 1.OpenGL & OpenGL ES 2.Android的硬體介面HAL 3.Android顯示裝置:Gralloc &  FrameBuff

學生管理系統ODBCSQL的配置連線

  雖然前幾天就一直在進行學生系統專案,但是在一開始的資料庫連結ODBC上就出現了問題,但是在今天半個小時的努力下,中功夫不負有心人完成了目標。下面是我登陸不成功出現的問題      出現這個問題的原因 SQL Server 相關連結的和密碼不匹配   解決方法如下:   首先,開啟

Android進階View.inflate和LayoutInflater.inflate方法區別

1 LayoutInflater用於載入佈局   LayoutInflater用於載入佈局的。載入佈局的任務通常都是在Activity中呼叫setContentView()方法來完成的。其實setContentView()方法的內部也是使用LayoutInflater來載入佈局的,只不過

Android ListView優化區域性重新整理(更新)(非notifyDataSetChanged)

在Android開發中我們經常會用到listview的資料和介面重新整理動作,我們每次可能會用到的都是Adapter.notifyDataSetChanged()方法。這個方法的原理是利用觀察者模式對我們的資料來源進行監聽,當我們的資料來源發生變化

Android顯示系統中VSYNC簡介

Android系統中關於VSYNC的簡介 92HWComposer::HWComposer( 93        const sp<SurfaceFlinger>&flinger, 94        EventHandler& handler)

Android系統基本問題研究

序:近年來Android智慧手機已成為人們生活的一部分,隨著Android手機功能的日益豐富,它正在改變不少行業的辦公模式。尤其是在警察、海關、銀行等行業,移動辦公顯得尤為迫切。如通過手機接入專有網路