4

Observer コールバックで Draw を実行しようとしていますが、キャンバスをロックしようとすると常に null が返されます。SurfaceHolder は問題ないようです。SurfaceHolder コールバックを追加すると、ゲームの早い段階で呼び出されます。

これが私のオブザーバーの更新方法です:

// implements Observer
public void update(Observable observable, Object data) {
   Canvas c = null;
   Log.i(TAG, "Surface Observer of CbSurfaceState thread: "
         + Thread.currentThread().getName());
   try {
      synchronized(mCbHolder) {
         c = mCbHolder.lockCanvas(null);
         if(c == null) {
             Log.i(TAG, "lockCanvas returned null");
          } else {
             doDraw(c);
          }
       }
    } finally {
       // do this in a finally so that if an exception is thrown
       // during the above, we don't leave the Surface in an
       // inconsistent state
       if (c != null) {
          mCbHolder.unlockCanvasAndPost(c);
       }
    }
}

初期化で最初に使用する場所は次のとおりです。

public void initCbSurfaceView(Context context) {
   mContext = context;
   // register our interest in hearing about changes to our surface
   mCbHolder = getHolder();
   Log.i(TAG,"got holder");
   mCbHolder.addCallback(cbSurfaceHolderCallback);
   Log.i(TAG,"added callback");
   // initially in preview mode
   mCbHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
   // previewHolder.(SurfaceHolder); Don't know how to replace, but it
   // won't work without the above.
   ...
   mCbSurfaceState.addObserver(this);
   Log.i(TAG, "Creation of CbSurfaceState thread: "
         + Thread.currentThread().getName());
}

サーフェスが作成されたときに再度設定することさえあります(念のために最近追加しました)

SurfaceHolder.Callback cbSurfaceHolderCallback = new SurfaceHolder.Callback() {
   @Override
   public void surfaceCreated(SurfaceHolder holder) {
      Log.i(TAG, "In surfaceCreated callback");
      mCbHolder = holder;
   }
   ...
};

ここにいくつかのログがあります。最初は非同期スレッドから開始されていたので、スレッドを印刷しましたが、それを回避することができました。

02-24 20:31:10.380: I/CbSurfaceView(4013): In surfaceCreated callback

02-24 20:31:10.380: I/CbSurfaceView(4013): SurfaceChanged 854X404

02-24 20:31:10.380: I/CbSurfaceView(4013): initPreview width 854 height 404

...

02-24 20:31:25.974: I/CbTouchListener(4013): onTouch Down x 665.7714 y 194.92023

02-24 20:31:25.974: I/CbSurfaceView(4013): Surface Observer of CbSurfaceState thread: main

02-24 20:31:25.981: I/CbSurfaceView(4013): lockCanvas returned null

02-24 20:31:26.005: I/CbSurfaceView(4013): Surface Observer of CbSurfaceState thread: main

02-24 20:31:26.075: I/CbSurfaceView(4013): lockCanvas returned null

私は一体何を間違っているのでしょうか?私のdoDrawは、ビットマップを描画しようとするまで機能していました。次に、lockCanvas から null をチェックすることを考えました。

ここで答えを見つけましたAndroidのカメラで使用されるSurfaceViewにオーバーレイを描画する方法は? プレビュー上では描画できないようです。PUSH_BUFFER タイプのサーフェスに関する例外が発生していたので、文句を言わないように NORMAL にリセットしました。プレビューのサーフェスをロックできず、NORMAL でない場合は例外がスローされました。どうやら、サーフェス タイプを動的に変更することはできません。それがおそらく廃止された理由ですが、カメラのプレビューは PUSH_BUFFER に設定しないと機能しません。撮影した写真を描画およびレンダリングするために、別の非サーフェス ビューを上に追加します。

ご覧いただきありがとうございます。これが誰かの役に立てば幸いです。

4

0 に答える 0