Androidオーディオおよびビデオ開発シリーズ-SurfaceViewの紹介

一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して6日目です。クリックしてイベントの詳細をご覧ください

SurfaceView

SurfaceViewソースコードから継承されますがView、内部実装SurfaceViewと他の実装Viewには多くの違いがあります。SurfaceView主な機能は、ビュー構造に埋め込まれた直接描画サーフェスを提供することです。これにより、実際に描画機能が実行されSurfaceます。したがって、SurfaceViewホストウィンドウとは別のものです。通常の状況では、ウィンドウViewは同じウィンドウを共有しますが、1つWindowWindowも対応しSurface、すべてView同じウィンドウを共有しSurfaceます。したがって、これはSurfaceView独立しています。Surfaceこれは、互いに干渉することなく、ホストウィンドウの描画から分離されていることと同じです。

違い

違い SurfaceView 意見
描く 構造はビューにありますが、描画面は独立しています。内部には、描画操作用の独自のキャンバスがあります ホストウィンドウと同じ描画面を共有します
リフレッシュ ウィンドウの更新では、ホストウィンドウを再描画する必要はありません 子要素または部分的な更新により、ビュー構造全体が再描画されます
スレッド スレッドは独立しており、インターフェイスを使用したメインスレッドの頻繁な更新には影響しません。 メインUIスレッドで使用
操作する 下位バージョンは、平行移動、ズーム、回転などのアニメーションをサポートしておらず、Viewプロパティコントロールを備えていません。 正常に動作できます
リフレッシュ 制御可能なリフレッシュレート、ダブルキャッシュメカニズム メインスレッドの更新のみを更新する

ダブルバッファーメカニズム

SurfaceViewビデオストリームを画像データ表示のフレームに解析します。たとえば、ある画像フレームが表示された後、次の画像フレームを待つことが時間内に解析されない場合があります。この場合、画像は滑らかになりません。この状況は、ダブルバッファリングを使用することで回避できます。ダブルバッファリングとは、2つのスレッドが交互にビデオストリームの画像データを解析し、解析とレンダリングの操作を交互に実行して、ビデオストリームをスムーズに再生できるようにすることを意味します。

SurfaceHolder

SurfaceViewダブルバッファリングメカニズムは、実際にはより多くのシステムメモリを消費します。したがって、表示されていない場合は、メモリのオーバーヘッドを減らすためSurfaceViewに破棄されます。SurfaceHolderしたがって、ステータスを監視するSurfaceHolder方法があります。addCallbackSurfaceHolder

  • void surfaceCreated(@NonNull SurfaceHolderholder);コールバックを作成します
  • void surfaceChanged(@NonNull SurfaceHolderホルダー、@ PixelFormat.Format int format、@ IntRange(from = 0)int width、@IntRange(from = 0)int height); 修改回调
  • void surfaceDestroyed(@NonNull SurfaceHolderholder);コールバックを破棄します

使用する

カスタム継承SurfaceViewを使用すると、描画される内容をカスタマイズできます。作成がSurfaceHolder成功したら、surfaceCreatedコールバックでlockCanvas取得したキャンバスを呼び出してSurfaceHolderロックし、コンテンツを描画します。描画が終了したら、unlockCanvasAndPostreleaseを呼び出してキャンバスの変更情報を送信し、新しいデータをキャンバスに表示できるようにします。

public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback{
    private SurfaceHolder mSurfaceHolder;
    private Canvas mCanvas;
    private Paint paint;

    public SurfaceViewTest(Context context) {
        this(context,null,0);
    }

    public SurfaceViewTest(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    private void init() {
        mSurfaceHolder = getHolder(); // 初始化
        mSurfaceHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 创建成功后就能通过线程绘制自定义内容
        new Thread(new Runnable() {
            @Override
            public void run() {
                draw();
            }
        }).start();
    }
    private void draw() {
        try {
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawCircle(500,500,300,paint);
            mCanvas.drawCircle(100,100,20,paint);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (mCanvas != null)
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}
}
复制代码

おすすめ

転載: juejin.im/post/7086047678727585822