问题描述:

I just started android programming this week and am curently working on a Live Wallpaper.

I have 2 Images, the Background Image (720x1280 png) and a slidebar (2276x290 png) that slides from right to left in an endles loop. my Problem is I only get it to slide with about 3-4fps with 1 px per Frame (on my actual phone, on AVD I get about 1/3fps ), wich is way to choppy for a live wallpaper. The code is working fine so far but way to slow.

It would be very nice if someone would know a way to get this "a lot" faster.

My code:

private class WEngine extends Engine {

private final Handler handler = new Handler();

private final Runnable drawRunner = new Runnable() {

@Override

public void run() {

draw();

}

};

private Paint paint = new Paint();

private int width;

int height;

private boolean visible = true;

int x = -1;

int x2 = 0;

int y = -1;

public WEngine() {

SharedPreferences prefs = PreferenceManager

.getDefaultSharedPreferences(WService.this);

handler.post(drawRunner);

}

@Override

public void onVisibilityChanged(boolean visible) {

this.visible = visible;

if (visible) {

handler.post(drawRunner);

} else {

handler.removeCallbacks(drawRunner);

}

}

@Override

public void onSurfaceDestroyed(SurfaceHolder holder) {

super.onSurfaceDestroyed(holder);

this.visible = false;

handler.removeCallbacks(drawRunner);

}

@Override

public void onSurfaceChanged(SurfaceHolder holder, int format,

int width, int height) {

this.width = width;

this.height = height;

super.onSurfaceChanged(holder, format, width, height);

}

private void draw() {

SurfaceHolder holder = getSurfaceHolder();

Canvas canvas = null;

Resources res = getResources();

Bitmap backgroundimg = BitmapFactory.decodeResource(res, R.drawable.background);

Bitmap slidebarimg = BitmapFactory.decodeResource(res, R.drawable.slidebar);

try {

canvas = holder.lockCanvas();

canvas.drawBitmap(backgroundimg, 0, 0, paint);

if (canvas != null) {

if (x<0 && y<0) {

x = 0;

y = Math.round(height / 2);

} else {

x -= 1;

}

if (x - width < -height * 1.778125) {

x2 -= 1;

}

if (x < -height * 1.778125) {

x = x2;

x2 = 0;

}

canvas.drawBitmap(slidebarimg, x, y, paint);

if (x2 < 0) {

canvas.drawBitmap(slidebarimg, x2, y, paint);

}

}

} finally {

if (canvas != null)

holder.unlockCanvasAndPost(canvas);

}

handler.removeCallbacks(drawRunner);

handler.postDelayed(drawRunner, 30);

}

}

Edit:

After changing the Images to jpg files I get about 6 fps, but thats still way to slow.

Edit 2:

I just figured out that hardwareaccceleration is not possible while using .lockCanvas()

Is there another way to draw an image on livewallpaper (surfaceview) that provides hardwareaccceleration?

网友答案:
private void draw() {
    ...
    Bitmap backgroundimg = BitmapFactory.decodeResource(res, R.drawable.background);
    Bitmap slidebarimg = BitmapFactory.decodeResource(res, R.drawable.slidebar);
    ...

Don't do this. If you're decoding bitmaps in every frame, it's going to be slow. Very slow. It doesn't matter if you're hardware accelerated or not. Decode them once, and just draw them on each frame.

网友答案:

There is OpenGl hardware texture size limit. In new devices it's mostly 2048px. Try keeping it your maximum. ( HW accelerated activity - how to get OpenGL texture size limit? ) Also make sure that hardware acceleration is on in your app http://developer.android.com/guide/topics/graphics/hardware-accel.html

相关阅读:
Top