歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android顯示系統之View與SurfaceView更新屏幕的區別

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

日期:2017/3/1 10:13:39   编辑:Linux編程

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://www.linuxidc.com/Linux/2012-08/67619.htm

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

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

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

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

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

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

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

4、Demo程序

  1. /*
  2. * author: conowen
  3. * e-mail: [email protected]
  4. * date : 2012.8.8
  5. */
  6. package com.conowen.viewtestdemo;
  7. import android.content.Context;
  8. import android.graphics.Canvas;
  9. import android.graphics.Color;
  10. import android.graphics.Paint;
  11. import android.graphics.RectF;
  12. import android.view.View;
  13. public class MyView extends View {
  14. private int counter;
  15. public MyView(Context context) {
  16. super(context);
  17. // TODO Auto-generated constructor stub
  18. }
  19. @Override
  20. protected void onDraw(Canvas canvas) {
  21. // TODO Auto-generated method stub
  22. super.onDraw(canvas);
  23. /* synchronized (this) {
  24. try {
  25. wait(10 * 1000);
  26. } catch (InterruptedException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  31. */
  32. // 設定Canvas對象的背景顏色
  33. canvas.drawColor(Color.YELLOW - counter);
  34. // 創建畫筆
  35. Paint p = new Paint();
  36. // 設置畫筆顏色
  37. p.setColor(Color.RED);
  38. // 設置文字大小
  39. p.setTextSize(40);
  40. // 消除鋸齒
  41. p.setFlags(Paint.ANTI_ALIAS_FLAG);
  42. // 在canvas上繪制rect
  43. canvas.drawArc(new RectF(100, 50, 400, 350), 0, counter, true, p);
  44. if (counter == 400) {
  45. counter = 0;
  46. }
  47. canvas.drawText("counter = " + (counter++), 500, 200, p);
  48. // 重繪, 再一次執行onDraw 程序
  49. invalidate();
  50. }
  51. }
效果圖:


打開下面的代碼,測試堵塞主UI線程(長按屏幕5秒以上)就會出現如下的圖。

  1. synchronized (this) {
  2. try {
  3. wait(10 * 1000);
  4. } catch (InterruptedException e) {
  5. // TODO Auto-generated catch block
  6. e.printStackTrace();
  7. }
  8. }

Copyright © Linux教程網 All Rights Reserved