我一直在嘗試儘可能多地從SurfaceView中擠出性能。目前,我將它繼承並實現了一個可運行的接口,而不是回調。我知道它沒有硬件加速。不過,如果我畫一個畫布原始垂直線在屏幕上或者垂直線上滾動,那麼在每次傳遞之後,它們都會運行得越慢越慢。這讓我感覺像內存泄漏,還是僅僅是Android本身? OpenGL或其他庫真的是我的最後一招?SurfaceView垂直線繪製在屏幕上速度太慢
我已經繪製了大量的滾動背景之前在體面的速度(我認爲每個蜱周圍5個像素,這是我瞄準20-50像素左右的勾號,如果有什麼東西會減少停止沿呈現的方式) 。
編輯:這裏是SurfaceView擴展,線程,繪製方法和初始化。基本上,這是一個稍微大一點的類,只是擁有這個屏幕的數據。 drawXYZ()
方法只是簡單地使用畫布基元或位圖來主要作爲背景進行繪製,這是一種純色的背景色,其上有一些垂直和水平的線條,就像音樂人員一樣,只涉及少量計算。
drawCursor
是什麼讓滾動垂直線,當我只是讓它循環滾動從左到右,它最終落後得比第一次滾動慢得多。
public class MySurfaceView extends SurfaceView implements Runnable
{
Thread renderThread = null;
SurfaceHolder holder;
volatile boolean running = false;
public MySurfaceView() {
super(mainActivity);
this.holder = getHolder();
holder.setFixedSize(screenW, screenH);
}
public void resume() {
running = true;
renderThread = new Thread(this);
renderThread.start();
}
@Override
public void run() {
while (running) {
if (!holder.getSurface().isValid()) {
continue;
}
Canvas canvas = holder.lockCanvas();
if(canvas != null) {
doDraw(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
}
public void pause() {
running = false;
while (true) {
try {
renderThread.join();
break;
} catch (InterruptedException e) {
// retry
}
}
}
protected void doDraw(Canvas canvas)
{
canvas.drawColor(Color.rgb(56, 56, 62));
lastNotePlayed = OptionsContainer.getNotePlaying();
//Draw contours (rows).
paint.setColor(Color.rgb(0, 255, 255));
paint.setStrokeWidth(3);
paint.setTextSize(35);
drawContours(canvas, paint);
//Beats per measure (BPM).
paint.setColor(Color.rgb(233, 232, 232));
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(bpmLines);
drawBPM(canvas, paint);
paint.setPathEffect(null);
//Draw measures.
paint.setStrokeWidth(5);
drawMeasures(canvas, paint);
//Draw note node inputs.
paint.setColor(Color.rgb(76, 255, 0));
for (int i = 0; i < OptionsContainer.noteList.length; i++) {
if (OptionsContainer.noteList[i].getContour() != 0) {
if (OptionsContainer.noteList[i].getContour() > (OptionsContainer.contour/2)) {
//Staff on left side, below note.
canvas.drawBitmap(lowerStaffBmp, OptionsContainer.noteList[i].getX(), OptionsContainer.noteList[i].getY(), null);
} else {
canvas.drawBitmap(higherStaffBmp, OptionsContainer.noteList[i].getX(), OptionsContainer.noteList[i].getY() - 40, null);
}
}
}
//Draw cursor.
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
drawCursor(canvas, paint);
if (OptionsContainer.isRest)
canvas.drawBitmap(restBmp, (OptionsContainer.screenWidth/2), (screenHeight - 100)/2, null);
}
}
@Override
public void init() {
surfaceView = new MySurfaceView();
surfaceView.setLayoutParams(layoutParams);
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
// Normalize x,y between 0 and 1
float x = event.getX();
float y = event.getY();
if (x < (OptionsContainer.screenWidth) && y < screenH) {
NoteNode note = new NoteNode(x, y, MainActivity.options);
if (note.getContour() == OptionsContainer.noteList[note.getBeat() - 1].getContour()) {
OptionsContainer.noteList[note.getBeat() - 1] = new NoteNode(x, screenHeight + 200, MainActivity.options);
} else {
OptionsContainer.noteList[note.getBeat() - 1] = note;
}
}
}
return true;
}
});
mainActivity.addContentView(surfaceView, layoutParams);
surfaceView.resume();
}
編輯#2:最終的答案
添加Path.reset()
的路徑在drawBPM()
繪製後。我想可能會阻止那條路徑的內存泄漏,它試圖跟蹤它已經寫入和覆蓋的所有路徑,對於我們的知識來說,只是看着屏幕上的線條。有一個類似的堆棧溢出問題,但下面的fadden的調試技巧是很有用有助於最初試圖找出哪裏出了問題。
DDMS顯示大多數內存似乎是主要的,但它與一般的觸摸事件處理和一切正常的應用程序調用。此外,所有這些位圖都被加載到內存中,但並不是每次調用都會發生這種情況。可以確認noteList沒有增長。看一下'drawCursor()'方法的時間間隔,平均大約90,000ns命中基本相同的數字。 – A13X
可以確認'doDraw()'方法正在減慢。將讓你全部張貼... – A13X
顯然,我所要做的只是重置'drawBPM()'方法的路徑?!現在它在屏幕上以相同的速度運行光標。非常感謝您提供調試技巧,部分答案也在這裏找到:http://stackoverflow.com/questions/9022766/are-paths-the-most-efficient-way-to-draw-changing-shapes – A13X