วันอาทิตย์ที่ 5 มกราคม พ.ศ. 2557

Android Graphics : SurfaceView



Android Graphics : SurfaceView
SurfaceView class is a View that handles a Surface, another class of the Android API.

What is a Surface? 
It’s an abstraction of a raw buffer that is used by the screen compositor for rendering that specific View. The screen compositor is the mastermind behind all rendering on Android, and is ultimately responsible for pushing all pixels to the GPU. The Surface can be hardware accelerated in some cases. We don’t care that much about that fact, though. All we need to know is that it is a more
direct way to render things to the screen.

Our goal is it to perform our rendering in a separate thread so that we do not hog the UI thread, which is busy with other things. The SurfaceView class provides us with a way to render to it from a thread other than the UI thread.

SurfaceHolder and Locking
In order to render to a SurfaceView from a different thread than the UI thread, we need to acquire an instance of the SurfaceHolder class, like this:

SurfaceHolder holder = surfaceView.getHolder();

The SurfaceHolder is a wrapper around the Surface, and does some bookkeeping for us. It provides us with two methods:

Canvas SurfaceHolder.lockCanvas();
SurfaceHolder.unlockAndPost(Canvas canvas);

The first method locks the Surface for rendering and returns a nice Canvas instance we can use. The second method unlocks the Surface again and makes sure that what we’ve drawn via the Canvas gets displayed on the screen. We will use these two methods in our rendering thread to acquire the Canvas, render with it, and finally make the image we just rendered visible on the screen. The Canvas we have to pass to the SurfaceHolder.unlockAndPost() method must be the one we received from the SurfaceHolder.lockCanvas() method.

The Surface is not immediately created when the SurfaceView is instantiated. Instead it is created asynchronously. The surface will be destroyed each time the activity is paused and recreated when the activity is resumed again.

SurfaceViewTest.java sourcecode


package android.example.surfaceview;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

public class SurfaceViewTest extends Activity {

      FastRenderView renderView;
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_surface_view);
       
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
            renderView = new FastRenderView(this);
            setContentView(renderView);
    }
   
    protected void onResume() {
      super.onResume();
      renderView.resume();
    }
   
    protected void onPause() {
      super.onPause();
      renderView.pause();
    }
   
   
    class FastRenderView extends SurfaceView implements Runnable {
     
      Thread renderThread = null;
      SurfaceHolder holder;
      Paint paint;
      Bitmap icon;
     
      volatile boolean running = false;
     
      public FastRenderView(Context context) {       
            super(context);        
            holder = getHolder();
            paint = new Paint();
           
            // Read from Drawable              
                  icon = BitmapFactory.decodeResource(getResources(),
                              R.drawable.ic_launcher);
      }
   
   
      public void resume() {
            running = true;
            renderThread = new Thread(this);
            renderThread.start();
      }
   
      public void pause() {
            running = false;
     
            while(true) {
     
                  try {
                        renderThread.join();
                  } catch (InterruptedException e) {
                  // retry
                  }
            }               
      }


      public void run() {
           
            while(running) {                   
                  if(!holder.getSurface().isValid())                   
                        continue;
                        Canvas canvas = holder.lockCanvas();
                        canvas.drawRGB(255, 0, 0);
                       
                        // Draw Line
                  paint.setColor(Color.WHITE);
                  canvas.drawLine(0, 0, canvas.getWidth()-1, canvas.getHeight()-1, paint);                    
                       
                        // Draw Rectangle
                        paint.setStyle(Style.FILL);
                  paint.setColor(0x77ffffff);               // White                 
                  canvas.drawRect(100, 100, 400, 400, paint);
                 
                  // Draw Circle
                  paint.setStyle(Style.STROKE);
                  paint.setColor(0xff00ff00);               // Green
                  canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, 80, paint);
                 
                  canvas.drawBitmap(icon, 140, 500, null);
                        holder.unlockCanvasAndPost(canvas);
            }                      
      }
   
    }
  
}




Android Graphics SurfaceView Example Code

ไม่มีความคิดเห็น:

แสดงความคิดเห็น