Android群英传——第六章SurfaceView

    xiaoxiao2021-12-04  16

    SurfaceView

    View通过刷新来重绘视图,Android系统通过发出VSYNC信号来进行屏幕重绘,刷新的间隔为16ms。如果在16ms内View完成了你所需要执行的所有操作。那么用户在视觉上就不会产生卡顿的感觉;而如果执行的操作逻辑太多,特别是需要频繁的刷新界面上,例如游戏界面, 那么就会不断的阻塞主线程,从而导致画面卡段。

    Skipped 47 frames!The Application may be doing too much work on its main thread

    这个警告的产生,很多情况下就是因为在绘制过程中,处理太多逻辑造成的。 所以SurfaceView就产生了。 SurfaceView继承自View,已知的直接子类有GLSurfaceView和VideoView,都是需要频繁刷新的View

    区别: - View主要用于主动更新的情况,SurfaceView主要用于被动更新,比如频繁的刷新操作 - View在主线程中对画面进行刷新,而SurfaceView通过一个子线程进行页面的刷新 - View没有双缓冲机制,而SurfaceView在底层实现机制中已经实现双缓冲机制

    双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。

    如果你的自定义View需要频繁的刷新,或者刷新时数据处理量较大,就可以使用SurfaceView来取代View

    使用SurfaceView绘制正弦曲线: code:

    import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * Created by feathers on 16-11-18. */ public class SurfaceViewDemo extends SurfaceView implements SurfaceHolder.Callback,Runnable{ // SurfaceHolder private SurfaceHolder mHolder; // 用于绘图的Canvas private Canvas mCanvas; //子线程标志位 private boolean mIsDrawing; private int x = 0; private int y = 0; private Path mPath; private Paint mPaint; public SurfaceViewDemo(Context context) { this(context, null); } public SurfaceViewDemo(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SurfaceViewDemo(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { // 初始化SurfaceHolder,并注册SurfaceHolder的回调方法 mHolder = getHolder(); mHolder.addCallback(this); setFocusable(true); setFocusableInTouchMode(true); this.setKeepScreenOn(true); // mHolder.setFormat(PixelFormat.OPAQUE); mPath = new Path(); mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); } // SurfaceView创建 @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { // 被创建后启动一个新的线程用来绘制 mIsDrawing = true; new Thread(this).start(); } // SurfaceView改变 @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { } // SurfaceView销毁 @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { // 销毁后,子线程结束 mIsDrawing = false; } @Override public void run() { while (mIsDrawing) { draw(); x += 1; y = (int) (100 * Math.sin(x * 2 * Math.PI / 180) + 400); mPath.lineTo(x, y); } } private void draw() { try { // 获取Canvas mCanvas = mHolder.lockCanvas(); // SurfaceView背景 mCanvas.drawColor(Color.WHITE); mCanvas.drawPath(mPath, mPaint); } catch (Exception e) { }finally { if (mCanvas != null) { mHolder.unlockCanvasAndPost(mCanvas); } } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); this.mCanvas = canvas; } }
    转载请注明原文地址: https://ju.6miu.com/read-680389.html

    最新回复(0)