Android显示系统之View与SurfaceView更新屏幕的区别
/********************************************************************************************
* author:conowen@大钟
* E-mail:conowen@hotmail.com
* http://blog.csdn.net/conowen
* 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。
********************************************************************************************/
1、View
Viewextends Object
implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource
Known Direct Subclasses(直接子类,SurfaceView是View的子类)
Known Indirect Subclasses(间接子类)
打开下面的代码,测试堵塞主UI线程(长按屏幕5秒以上)就会出现如下的图。
注意: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, callpostInvalidate().
如下面的代码所示。这样的话,就不必担心主UI线程被堵塞了。
/* * author: conowen * e-mail: conowen@hotmail.com * date : 2012.8.4 */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;private Thread mThread;public MyView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);mThread = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtry {mThread.sleep(10 * 1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 重绘, 再一次执行onDraw 程序invalidate();postInvalidate();}});mThread.start();// 设定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);}}
