Android(java)学习笔记187:多媒体之SurfaceView
1. SurfaceView:
完成单位时间内界面的快速切换(游戏界面流畅感)。
我们之前知道一般的View,只能在主线程里面显示,主线程中更新UI。但是SurfaceView可以在子线程中里面更新UI。
SurfaceView内置了双缓冲的技术,SurfaceView一旦启动,就会对应两个线程(线程A 和 线程B);
(1)线程A是前台,线程B是后台线程;
(2)线程A开始进行UI显示,(与此同时)线程B计算处理下一个UI的显示,A执行完了,B也执行完了;
(3)这时候,线程A和线程B快速切换角色,这时候线程B是前台进程,线程A是后台进程;
(4)这时候,线程B前台显示UI,线程A后台计算处理;B执行完了,A也执行完了;
(5)这时候,线程B和线程A快速切换角色,这时候线程A是前台进程,线程B是后台进程;
(6)如此反复;
2.案例演示使用SurfaceView,如下:
(1)activity_main.xml,如下:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context=".MainActivity" > 6 7 8 <SurfaceView 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_centerHorizontal="true" 12 android:layout_centerVertical="true" 13 android:id="@+id/sv"/> 14 15 </RelativeLayout>
(2)MainActivity,如下:
1 package com.itheima.surfaceview; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.graphics.Canvas; 6 import android.graphics.Color; 7 import android.graphics.Paint; 8 import android.view.Menu; 9 import android.view.SurfaceHolder; 10 import android.view.SurfaceHolder.Callback; 11 import android.view.SurfaceView; 12 import android.view.View; 13 14 public class MainActivity extends Activity { 15 private SurfaceView sv; 16 private Paint paint; 17 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 sv = (SurfaceView) findViewById(R.id.sv); // 舞台 23 24 paint = new Paint(); 25 paint.setColor(Color.RED); 26 final SurfaceHolder holder = sv.getHolder(); // 导演, 导演控制如何显示。 27 28 holder.addCallback(new Callback() { 29 30 @Override 31 public void surfaceDestroyed(SurfaceHolder holder) { 32 System.out.println("界面被销毁了"); 33 } 34 35 @Override 36 public void surfaceCreated(final SurfaceHolder holder) { 37 System.out.println("界面才被创建出来"); 38 new Thread() { 39 public void run() { 40 for (int i = 0; i < 500; i++) { 41 Canvas canvas = holder.lockCanvas(); 42 canvas.drawCircle(200, 200, i, paint); 43 holder.unlockCanvasAndPost(canvas); 44 try { 45 Thread.sleep(2); 46 } catch (InterruptedException e) { 47 e.printStackTrace(); 48 } 49 } 50 }; 51 }.start(); 52 } 53 54 @Override 55 public void surfaceChanged(SurfaceHolder holder, int format, int width, 56 int height) { 57 58 } 59 }); 60 } 61 62 63 }
SurfaceView的这个控件,内存开销比较大;如果把SurfaceView放到onCreate里面会容易产生出现空指针,因为onCreate中调用SurfaceView的时候,可能SurfaceView还没有创建好,调用它当然就是空指针异常。
这里利用SurfaceHolder的一个API,就是addCallback(……),这里接口实现类有个方法是:
public void surfaceCreated(SurfaceHolder holder),它就是在SurfaceView创建完毕,之后调用的方法。