7

私は自分の問題を回避する方法を見つけようとしています。http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664を読んだことがありますが、私が知る限り、それは一種の「タフな運」の答え。だからここに私の問題があります:

通常の方法(lock / unlockAndPost)でSurfaceViewを使用して、サーフェスが変更されるたびにゲームの背景のビットマップを描画し(方向など)、一連の移動する円(半径が最大30)をレンダリングしています。約25.f)。これらの円の位置のx、yデータはサーバーからのものであり、すべて正常に実行されます。すべての円オブジェクトはリストに保存され、この更新が同期されるように注意してそれらの位置が更新されます。ただし、これらの円を画面に描画すると(canvas.lock()中)、ほとんどの場合、うまくレンダリングされますが、フレームの一部の円が一時的に裂けたりちらついたりすることがあります(たとえば、数秒に1回)。円の数は常に一定であるため、問題はなく、円のリストが同時に変更されることはありません(前述のとおり、同期されています)。これらすべての円を各レンダリングループのビットマップに描画し、そのビットマップをメインキャンバスに描画してみました。これはパフォーマンスにさらに影響を与えるようです(メインキャンバスに直接円を描く場合は〜30FPSではなく〜13FPS)。情報が少し漠然としている場合は申し訳ありませんが(会社を幸せに保つために:p)、誰かが私に手がかりを与えることができるかどうか疑問に思っていましたか?それとも私は運が悪かったのですか。サーバーからの測位データはリアルタイムデータであり、レンダリングがこれらのリアルタイムの位置を反映することが非常に重要であることに注意する必要があります。情報が少し漠然としている場合は申し訳ありませんが(会社を幸せに保つために:p)、誰かが私に手がかりを与えることができるかどうか疑問に思っていましたか?それとも私は運が悪かったのですか。サーバーからの測位データはリアルタイムデータであり、レンダリングがこれらのリアルタイムの位置を反映することが非常に重要であることに注意する必要があります。情報が少し漠然としている場合は申し訳ありませんが(会社を幸せに保つために:p)、誰かが私に手がかりを与えることができるかどうか疑問に思っていましたか?それとも私は運が悪かったのですか。サーバーからの測位データはリアルタイムデータであり、レンダリングがこれらのリアルタイムの位置を反映することが非常に重要であることに注意する必要があります。

助けてくれてありがとう!クリス

編集:

けっこうだ。これがレンダリングスレッドからのrun()です。

@Override
    public void run() {
        Canvas c;
        while (mRun) {
            c = null;
            try {
                c = mSurfaceHolder.lockCanvas(null);
                synchronized (mSurfaceHolder) {
                    panel.onDraw(c);
                }
            } finally {
                if (c != null) {
                    mSurfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }

かなり標準的なもの(月着陸船のほぼカーボンコピー:p)

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mBackground= Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.RGB_565);
    screenOrientation = getResources().getConfiguration().orientation;
    if(thread.getState()== Thread.State.TERMINATED){
        thread = new RenderThread(holder, this);
        thread.setRunning(true);
        thread.start();
    }else {
        thread.setRunning(true);
        thread.start();
    }
}



@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    Canvas c = new Canvas(mField);
    c.drawARGB(255,0,144,0);
    backgroundDetails.renderOnPanel(c, this);
    screenOrientation = getResources().getConfiguration().orientation;
}

非常に簡単にフォローできます。向きが変わった場合は背景のビットマップを再描画して、レンダリングスレッドを開始してください。

public void onDraw(Canvas canvas) {
    canvas.drawBitmap(mField,0,0,null);
    drawPositionBeans(canvas, this);
}

そして最後に:

    public void onDraw(Canvas canvas, RadarView radarView) {
    float beanX=0, beanY=0;
    float radius = 25.0f;
    final List<PositionBean> copyOfList = Collections.synchronizedList(positionBeans.getPositionBeans());
    synchronized(copyOfList){
        try {
            for (final PositionBean pb : copyOfList)
            {
                if (panel.getOrientation() == Configuration.ORIENTATION_PORTRAIT) {
                    beanX = (float)pb.getY()*(-1);
                    beanY = (float)pb.getX();
                } else {
                    beanX = (float)pb.getY()*(-1);
                    beanY = (float)pb.getX()*(-1);
                }
                mPaint.setARGB(255,pb.getRgbColor().getR(), pb.getRgbColor().getG(), pb.getRgbColor().getB());
                panel.drawSpot(canvas, beanX, beanY, radius, mPaint);

                mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setARGB(255,255,222,1);
                for (int j = 0; j < selectedBean.size(); ++j)
                {
                    if(pb.getTrack()==selectedBean.get(j)) {
                        panel.drawSpot(canvas, beanX, beanY, radius+1, mPaint);
                    }
                }
                mPaint.setStyle(Paint.Style.FILL);
            }

        } catch(Exception e) {
            Log.e("render", "Exception Drawing Beans: " + e);
        }
    }
}

みんなありがとう。クリス

4

4 に答える 4

1

優れた説明と可能な回避策を紹介します

http://android-coding.blogspot.ca/2012/01/flickering-problems-due-to-double.html

于 2012-03-20T01:08:17.143 に答える
1

これは、Android グラフィックスにバッファ サーフェスと可視サーフェスがあり、それらが常に利用可能であることを確認するために単純に交互に使用されているために発生しています。つまり、あるフレームで描画すると、すべてのフレームで描画しない限り、次のフレームには表示されません。

http://groups.google.com/group/android-developers/msg/8d1243c33f9b7b6e?pli=1

于 2011-03-15T18:05:32.013 に答える
1

私はその問題を抱えていました。私に適した解決策は、onDraw メソッドと変換行列を更新するメソッドの同期です。マトリックスが同一のフレーム (new Matrix() の初期値) があり、次のフレームでは正しい値があったためです。

于 2011-01-05T20:06:05.510 に答える
0

表面ビューについて少し読んだ後、あなたが呼び出すと

getHolder().lockCanvas();

すべてをもう一度描く必要があります。

ダーティエリアを提供しない限り。

getHolder().lockCanvas(Rect dirty);

Rect で定義された領域のみを再描画する場合

于 2015-06-05T16:20:02.093 に答える