SurfaceView

来源:互联网 发布:小黑屋写作软件免费版 编辑:程序博客网 时间:2024/06/05 15:20

在开始本文之前先看一段Log

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

这个警告大多数是在自定义View时产生的,而其中在绘制过程中处理逻辑太多、刷新数据量比较大是主要原因
因为逻辑和刷新的数据一般和产品的效果或逻辑有关,优化的空间有限,如果对产品流程性要求很高就需要用新的东东来实现了。Android提供了SurfaceView就是来处理这种情形的。

View通过刷新来重绘视图,Android系统通过发出VSYNC信号来进行屏幕绘制,刷新时间间隔为16ms。如果18ms内View完成了你所须要执行的操作,那么在视觉上就不会参数卡顿;但是当执行逻辑或处理数据较多时,特别是需要频繁刷新的界面上,就会阻塞主线程导致画面卡顿。如:相机取景、视频播放、游戏界面绘制。普通应用最容易遇到的场景,在获取网络数据时加载动画,数据解析完毕隐藏动画显示UI。如果解析的数据量很大,在数据返回到解析完毕情况动画就会卡顿一下。

SurfaceView和View的主要区别:

  • View主要适用于主动更新,SurfaceView主要适用于被动、频繁更新
  • View在主线程中对画面进行刷,SurfaceView通常会通过一个子线程进行页面刷新
  • View在绘制是没有使用双缓冲机制,而SurfaceView在底层实现机制中已经实现了双缓冲机制

因为SurfaceView使用子线程更新页面,因此在有交互场景是会带来事件同步问题

下面是标准的SurfaceView的使用模板

class MyView extends SurfaceView implements SurfaceHolder.Callback,Runnable{          boolean isRunning;         SurfaceHolder holder;          Canvas canvas;        public MyView(Context context) {              super(context);              initView();        }        //初始化       private void initView()       {        // TODO Auto-generated constructor stub              holder = getHolder();              holder.addCallback(this);             setFocusable(true);             setFocusableInTouchMode(true);            this.setKeepScreenOn(true);       }       //SurfaceView创建         @Override          public void surfaceCreated(SurfaceHolder holder) {              // TODO Auto-generated method stub             isRunning = true;             Thread t=new Thread(this);              t.start();          }         //SurfaceView改变       @Override          public void surfaceChanged(SurfaceHolder holder, int format, int width,                  int height) {              // TODO Auto-generated method stub          }         //SurfaceView销毁        @Override          public void surfaceDestroyed(SurfaceHolder holder) {              // TODO Auto-generated method stub              isRunning = false;          }        // Runnable接口,Run方法的实现             @Override          public void run() {              while (isRunning) {                   onDraw();                              }          }         //绘制内容方法        @Override          protected void onDraw() {               try {                    canvas = holder.lockCanvas();                   //draw something                } catch (InterruptedException e) {                  } finally{//确保每次都能将内容提交                  if(canvas != null)                  {                    holder.unlockCanvasAndPost(canvas);                  }                }         }      }  
0 0