AndroidのSurface View(一)

8520 ワード

まず、公式APIによるSurface Viewの紹介を見てみましょう.
Surface ViewのAPI紹介
   Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen
  The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
  Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder().
The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.
  One of the purposes of this class is to provide a surface in which a secondary thread can render in to the screen. If you are going to use it this way, you need to be aware of some threading semantics:
  •All SurfaceView and SurfaceHolder.Callback methods will be called from the thread running the SurfaceView's window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.    •You must ensure that the drawing thread only touches the underlying Surface while it is valid -- between SurfaceHolder.Callback.surfaceCreated() and SurfaceHolder.Callback.surfaceDestroyed().対応する中国語翻訳Surface Viewはビュー(View)の継承クラスで、このビューには描画専用のSurfaceが埋め込まれています.このSurfaceのフォーマットとサイズを制御することができます.Surfaceビューは、このSurfaceの描画位置を制御します.surfaceは奥行きソート(Z-ordered)であり,これは常に自分のウィンドウの後ろにあることを示している.surfaceviewは、この可視領域内のsurface部分の内容のみが表示され、可視領域外の部分は表示されない可視領域を提供する.surfaceのレイアウト表示は、ビューレベル関係の影響を受け、その兄弟ビューノードが先頭に表示されます.これは、surfaceの内容が兄弟ビューによって遮断されることを意味し、この特性は、テキストやボタンなどのコントロールを配置するために使用することができる.surfaceに透明なコントロールがある場合、その変更のたびにフレームワークが最上位のコントロールと透明な効果を再計算し、パフォーマンスに影響を与えることに注意してください.このsurfaceにSurfaceHolderインタフェースでアクセスでき、getHolder()メソッドでこのインタフェースを得ることができます.surfaceviewが表示されるとsurfaceが作成されます.surfaceviewが非表示になる前にsurfaceが破棄されます.これにより、リソースを節約できます.surfaceが作成および破棄されるタイミングを確認する場合は、surfaceCreated(SurfaceHolder)とsurfaceDestroyed(SurfaceHolder)を再ロードできます.surfaceviewの核心は、UIスレッドとレンダリングスレッドの2つのスレッドを提供することです.ここで注意すべきことは、1>すべてのSurface ViewとSurface Holder.Callbackの方法はUIスレッドで呼び出すべきで、一般的にはアプリケーションのメインスレッドです.レンダリングスレッドがアクセスする変数は、同期処理を行う必要があります.2>surfaceは破棄される可能性があるため、SurfaceHolderのみである.Callback.surfaceCreated()とSurfaceHolder.Callback.surfaceDestroyed()間は有効なので、レンダリングスレッドが正当で有効なsurfaceにアクセスしていることを確認します.
      
次に、自分の理解1、定義について話します.
メモリやDMAなどのハードウェアインタフェースから直接画像データを取得できる、非常に重要な描画コンテナです.
メインスレッド以外のスレッドでスクリーンに図面を描くことができるのが特徴です.これにより、グラフィックタスクが重い場合にプライマリスレッドがブロックされることを回避し、プログラムの反応速度を向上させることができる.ゲーム開発ではSurfaceViewが多く使われており、ゲームの背景や人物、アニメーションなどはキャンバスcanvasにできるだけ描かれている.
2、実現
まずSurfaceViewを継承し、SurfaceHolderを実現する.Callbackインタフェースがインタフェースを使用する理由:Surface Viewを使用するには原則があるため、すべての描画作業は、Surfaceが作成されてから開始する必要があります(Surface-表面、この概念はグラフィックプログラミングでよく取り上げられています.基本的には、Surfaceに書き込まれたコンテンツを直接表示にコピーして表示することができ、表示速度が非常に速くなります).Surfaceが破棄される前に終了しなければなりません.したがってCallbackのsurfaceCreatedとsurfaceDestroyedは描画処理コードの境界となる.
書き換えが必要な方法
 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}
//surfaceのサイズが変わったときに励起
 (2)public void surfaceCreated(SurfaceHolder holder){}
//作成時に励起され、一般的にここで図面のスレッドが呼び出されます.
 (3)public void surfaceDestroyed(SurfaceHolder holder) {}
//破棄時に励起され、一般的にここで図面のスレッドを停止、解放します.
プロセス全体:SurfaceViewを継承し、SurfaceHolderを実現する.Callbackインタフェース->Surface View.getHolder()SurfaceHolderオブジェクトを取得する->SurfaceHolder.addCallbackコールバック関数->Surface Holderを追加します.lockCanvas()Canvasオブジェクトを取得し、キャンバス->Canvasペイント->SurfaceHolderをロックします.unlockCanvasAndPost(Canvas canvas)は、図面のロックを終了し、変更をコミットしてグラフィックを表示します.
3、SurfaceHolderここではsurfaceのコントローラとしてsurfaceを操作するためのクラスSurfaceHolderを使用しています.Canvasで描かれた効果やアニメーションを処理し、表面、サイズ、ピクセルなどを制御します.いくつかの注意すべき方法:(1)、abstract void addCallback(SurfaceHolder.Callback callback);//Surface Viewの現在の所有者にコールバックオブジェクトを与えます.(2)、abstract Canvas lockCanvas();//キャンバスをロックすると、一般的にはロック後に戻るキャンバスオブジェクトCanvasを介して、その上に絵を描くなどの操作ができます.(3)、abstract Canvas lockCanvas(Rect dirty);//キャンバスの領域をロックして絵を描くなど..図を描くと、次のunlockCanvasAndPostを呼び出して表示内容を変更します.//部分メモリの要求が比較的高いゲームに対してdirty外の他の領域の画素を再描画することなく、速度を向上させることができる.(4)、abstract void unlockCanvasAndPost(Canvas canvas);//図面のロックを終了し、変更をコミットします.
コード:
新しいMyviewクラス継承とSurface Viewを作成してviewを描画します.
<pre style="font-family:   ; font-size: 12pt; background-color: rgb(255, 255, 255);"><span style="color:#000080;background-color:#e4e4ff;"><strong></strong></span>
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 *    
 * Created by Young on 2015/5/2.
 */
public class MyView extends SurfaceView implements SurfaceHolder.Callback{
    private SurfaceHolder holder;
    private MyThread myThread;
    public MyView(Context context) {
        super(context);
        //holder= this.getHandler().addCallback(this);
        holder = this.getHolder();//  holder
        holder.addCallback(this);
        myThread=new MyThread(holder);//        
    }

    //      ,            。
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        myThread.isRun=true;
        myThread.start(); //         Canvas   
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        myThread.isRun=false;
    }

    class MyThread extends Thread{

        private SurfaceHolder holder;
        public boolean isRun;
        public  MyThread(SurfaceHolder holder){
            this.holder=holder;
            isRun=true;
        }

        @Override
        public  void  run(){

            int count=0;
            while(isRun){
                Canvas c=null;

                try {
                    synchronized (holder)
                    {
                        c=holder.lockCanvas();//    ,                   Canvas,          。
                        c.drawColor(Color.WHITE);//        
                        Paint paint=new Paint();//    
                        paint.setColor(Color.YELLOW);//    
                        Rect rect=new Rect(100,50,300,250);
                        c.drawRect(rect,paint);
                        Paint paint1=new Paint();//    
                        paint1.setColor(Color.BLACK);//    
                        paint1.setTextSize(20);//    
                        c.drawText("   " + (count++) + " ", 500, 100, paint1);
                        Thread.sleep(1000);//     1s
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                finally {
                    if (c!=null){
                        holder.unlockCanvasAndPost(c);//      ,     。
                    }
                }
            }
        }
    }

}
 
  
 

在Main_activity.java中加载MyView所创造出来的页面。

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));

       // MyView myView=new MyView(this);
    }
}