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创建完毕,之后调用的方法

原文地址:https://www.cnblogs.com/hebao0514/p/4805465.html