3

典型的な Android グラフィックス フローに従うのに少し問題があります。多くの例がありますが、私のものはうまくいかないようです。私の主な活動では、これを行います:

super.onCreate(savedInstanceState);                           
setContentView(R.layout.activity_main); 

私のリソース ファイルには、SurfaceView をオーバーライドする 3 つのカスタム クラスがあります。これらのサーフェス ビューのコンストラクターには、次のようなものがあります。

super(context, attrs);
getHolder().addCallback(this);
this.thread = new MyThread(getHolder(),this);

私のスレッドの run メソッドでは、これを行います (私が見た多くの例から取り上げました):

Canvas c;
try {
    c = surfaceHolder.lockCanvas(null);
    synchronized (surfaceHolder) {
        panel.onDraw(c);
    }
} finally {
    if (c != null) {
    surfaceHolder.unlockCanvasAndPost(c);
}

このスレッドは、SurfaceView の「surfaceCreated」イベントで開始されます。onDraw では、次のようにします。

public void onDraw(Canvas canvas) { 
    super.onDraw(canvas);
    <some drawing stuff here using canvas>
}

実行すると、スレッドは実際に実行され、onDraw が呼び出されていることがわかります (log print コマンドをそこに入れました) が、グラフィックが期待どおりに更新されません。ただし、 this.invalidate() を呼び出すと、これでクラッシュするまで、予想どおりグラフィックが数回更新されます。

E/AndroidRuntime(748): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

私が見た例によれば、OnDraw で invalidate を呼び出す必要はないことを認識していますが、onDraw のコードが有効であることを確認するためだけに呼び出しました。したがって、invalidate() がないと onDraw イベントが呼び出され、私のコードはグラフィックを適切に更新する必要があるように思えますが、画面は更新されません。メインのアクティビティが実際に子供を再描画する必要があると判断する方法に欠けています。

どんなアイデアでも大歓迎です。いくつかの動作中のデモからコピーしようとしてしばらく時間を費やしましたが、行き詰まっているようです。ありがとう

4

2 に答える 2

0

私はすでに同じ問題を抱えていました。解決策が見つからなかったので、一種の回避策を実行しBitmapました。バッファとして a を作成し、そのビットマップに描画します。描画後、完全なビットマップをビュー自体に描画します。View クラスで次の変数を宣言します。

Canvas bmpCanvas;
Bitmap bmp;

そして、次のように onDraw() メソッドで使用します。

@Override
protected void onDraw(Canvas canvas) {

   if(bmp == null || bmpCanvas == null) {

       bmp = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
       bmpCanvas = new Canvas(bmp);
   }

   //do drawing-stuff here

   canvas.drawBitmap(bmp, 0, 0, p); //where p is a Paint-Object.
}

ここで、ビューを更新する/このメソッドを呼び出すには、メソッドを同じスレッドで呼び出すか他のスレッドで呼び出すかに応じて、またはビューのいずれinvalidateかを使用します。postInvalidate() invalidate

于 2014-11-03T16:16:57.463 に答える
0

run() で行うことは、何をしても構いません - 一度。描画プロセスを繰り返す必要があります。

1 つの方法は、すべてをwhileループ内に配置することです。

while(true){
    try {
        c = surfaceHolder.lockCanvas(null);
        synchronized (surfaceHolder) {
            panel.onDraw(c);
        }
    } finally {
        if (c != null) {
        surfaceHolder.unlockCanvasAndPost(c);
    }
}
于 2012-09-07T05:05:43.383 に答える