背景がスクロールするライブ壁紙に取り組んでいます。次のフレームのために以前に描画されたピクセルを保持するために、2 つのビットマップ オブジェクトを交互に使用します。キャンバスの上部に新しい線を描画し、drawBitmap を呼び出して残りのピクセルをキャンバスにコピーします。
Runnable オブジェクトを使用して重い作業を行っています。必要なすべてのコピーと計算を実行してから、キャンバスをロックし、ホルダーで同期ブロックに入り、Canvas.drawBitmap(bitmap,rect,rect,paint) を 1 回呼び出します。時折、画面に白い閃光が現れることがありますが、これは CPU の使用率が高いことと関連しているようです。traceview を使用すると、drawBitmap 操作、具体的には Canvas.native_drawBitmap() に通常よりもはるかに長い時間がかかっていることがわかりました。通常は 2 ~ 4 ミリ秒で完了しますが、白い閃光が見えると、10 ~ 100 ミリ秒かかることがあります。
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
prepareFrame();
try {
canvas = holder.lockCanvas();
synchronized (holder) {
if (canvas != null) {
drawFrame(canvas);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
holder.unlockCanvasAndPost(canvas);
}
afterDrawFrame();
handler.removeCallbacks(drawRunner);
if (visible) {
handler.post(drawRunner);
}
}
draw()
関数はrun()
Runnableので呼び出されます。
private void prepareFrame() {
num++;
if (num%2 == 0) {
mainBmp = mainBmp1;
mainCan.setBitmap(mainBmp1);
mainCan.drawBitmap(mainBmp2, source, destination, null);
} else {
mainBmp = mainBmp2;
mainCan.setBitmap(mainBmp2);
mainCan.drawBitmap(mainBmp1, source, destination, null);
}
}
関数は、prepareFrame()
以前に描画したピクセルを保持する方法です。source と呼ばれる Rect は、下部が全画面サイズより 1 行不足しており、宛先が上部で 1 行不足しています。のdrawBitmap()
呼び出しはprepareFrame()
2 ~ 4 ミリ秒よりも長くはありません。
private void drawFrame(Canvas can) {
can.drawBitmap(mainBmp, source, destination,null);
}
この単一の操作は、ロックを保持しながらキャンバス上で行われます。
private void afterDrawFrame() {
ca.calcNextRow();
mainBmp.setPixels(ca.getRow(), 0, canWidth, 0, 0, canWidth, 1);
}
次に、ピクセルの次の新しい行が、メモリ内のビットマップの 1 つに描画されます。
のさまざまなシグネチャを使用してdrawBitmap()
みましたが、平均して遅く、異常な白いフラッシュが発生するだけでした。
私の全体的な速度は素晴らしいです。断続的なフラッシュがなければ、非常にうまく機能します。フラッシュをなくす方法について誰か提案がありますか?