Android-SurfaceView的总结

Android-SurfaceView的总结

缘由:

Android系统提供View进行绘图处理,但是很多时候会显得心有余而力不足,比如当view绘图进行大量的操作,容易使主线程阻塞,并且在logcat输出···

"skipped 47 frames! the application may be doing much work in main thread"

这个当我在页面进行大量的视图动画时,经常出现。

所以当你的View需要频繁的刷新,或者刷新时数据处理量比较大时,建议使用SurfaceView。

View绘图方式:

View是通过刷新来更新视图。系统通过发送VSYnc信号来通知屏幕进行刷新,刷新频率为16ms,因此当你的View刷新时间超过16ms,就会出现卡顿。

View和surfaceView的比较:

1.view适用于主动进行画面更新,而surfaceView适合被动进行更新。

2.view更新运行在主线程,容易造成主线程的阻塞,而surfaceView运行在新的子线程中。

3.VIew绘图没有使用双缓冲机制,而surfaceView底层已经实现双缓冲机制。

说明:双缓冲机制--当要在指定View上绘制图形时,不直接在View上绘制,而是先绘制到内存中的Bitmap图片上,等到缓存的Bitmap 绘制好,以后,再将bitmap上的直接绘制View组件上。

surfaceView的使用:

1.继承自SurfaceView,实现SurfaceHolder,CallBack,Runnable接口

2.并且重写抽象方法

2.在xml文件中使用或者动态生成

实例代码:

public class KillView extends SurfaceView  implements SurfaceHolder.Callback,Runnable{

private SurfaceHolder holder;
private Canvas canvas;
private boolean isDrawing;
private Paint paint;

public KillView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

public KillView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public KillView(Context context) {
super(context);
init();
}

public void init(){
Log.e("TAG","init");
holder=getHolder();
holder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
Path path;

@Override
public void run() {
long start=System.currentTimeMillis();
   while (isDrawing){
        draw();
}
long end=System.currentTimeMillis();
Log.e("TAG","start="+start+" end="+end);
if(end-start<100){
try{

Thread.sleep(100-end+start);
}catch (Exception e){
e.printStackTrace();
}
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e("TAG","create");
isDrawing=true;
path=new Path();
paint=new Paint();
paint.setColor(getResources().getColor(R.color.colorAccent));
new Thread(this).start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.e("TAG","change");
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e("TAG","destroy");
isDrawing=false;


}

   public void draw(){
   try{
   canvas=holder.lockCanvas();
   canvas.drawCircle(getWidth()/2,getWidth()/2,100,paint);
   holder.unlockCanvasAndPost(canvas);
   canvas=holder.lockCanvas();
   canvas.drawColor(Color.WHITE);
   //canvas.drawPath(path,paint);
   canvas.drawArc(0,0,100,100,0,360,true,paint);
   }catch (Exception e){
  throw new IllegalArgumentException();
   }finally{
   if(holder!=null){
   holder.unlockCanvasAndPost(canvas);
   }
   }
        }
    }

代码中方法说明:

1.getHolder()

surfaceView 一般与surfaceHolder结合使用,surfaceHolder用于向关联的View绘图 ,可通过getHolder方法获得当前View的holder。

2.lockCanvas()

锁定surfaceView对象,获取surfaceView上的Canvas对象。

3.unlockCanvasANdPost()

当调用该方法时,之前绘制的内容还在内存中,当下次lockCanvas()时,可能会覆盖之前的内容,因此如果想要持久化绘制内容,添加以下代码:

holder.lockcanvas(new Rect(0,0,0,0);
holder.unlockcanvasAndPost(canvas);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值