日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android显示系统之View与SurfaceView更新屏幕的区别

發布時間:2025/4/5 Android 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android显示系统之View与SurfaceView更新屏幕的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

/********************************************************************************************
* author:conowen@大鐘?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
* E-mail:conowen@hotmail.com????????????????????????????????????????????????????????????????????????????????????????????????????????????
* http://blog.csdn.net/conowen ????????????????????????????????????????????????????????????????????????????????????????????????????????????
* 注:本文為原創,僅作為學習交流使用,轉載請標明作者及出處。?????


http://blog.csdn.net/conowen/article/details/7843487

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


1、View


View

extends Object
implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource
java.lang.Object
?? ?android.view.View
Known Direct Subclasses(直接子類,SurfaceView是View的子類) AnalogClock,ImageView,KeyboardView,MediaRouteButton,ProgressBar,Space,SurfaceView,TextView,TextureView,ViewGroup,ViewStub
Known Indirect Subclasses(間接子類) AbsListView,AbsSeekBar,AbsSpinner,AbsoluteLayout,AdapterView<T extends Adapter>,AdapterViewAnimator,AdapterViewFlipper,AppWidgetHostView,AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, and 53 others.

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.). TheViewGroup 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的詳細可以參看之前的博文

http://blog.csdn.net/conowen/article/details/7821409

Android更新屏幕主要有兩種方式,繼承SurfaceView實現SurfaceHolder.callback接口來實現屏幕的更新。

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

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


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


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


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


所以當更新操作說花的時間較長,而且數據量較大的話,一般采用SurfaceView方式更新屏幕,而少用View。


4、Demo程序

[java] view plaincopyprint?
  • /*
  • * author: conowen
  • * e-mail: conowen@hotmail.com
  • * 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();?
  • ?
  • ??? }?
  • ?
  • }?
  • /** author: conowen* e-mail: conowen@hotmail.com* 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}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas); /* synchronized (this) {try {wait(10 * 1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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上繪制rectcanvas.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秒以上)就會出現如下的圖。

    [java] view plaincopyprint?
  • synchronized (this) {?
  • ??????????? try {?
  • ??????????????? wait(10 * 1000);?
  • ??????????? } catch (InterruptedException e) {?
  • ??????????????? // TODO Auto-generated catch block?
  • ??????????????? e.printStackTrace();?
  • ??????????? }?
  • ??????? }?
  • synchronized (this) {try {wait(10 * 1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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, onDraw(android.graphics.Canvas) 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 postInvalidate().


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

    [java] view plaincopyprint?
  • /*
  • * author: conowen
  • * e-mail: conowen@hotmail.com
  • * 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);?
  • ?
  • ??? }?
  • ?
  • }?
  • http://blog.csdn.net/conowen/article/details/7843487
  • 總結

    以上是生活随笔為你收集整理的Android显示系统之View与SurfaceView更新屏幕的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。