5

I am working on a livewallpaper for Android. The code works, but I have performance issues. Basically I am drawing Bitmaps and move them. With 15 small images it workes fine. But with 50 bigger images it starts lagging.

In my moving object I am creating the Bitmap in the constuctor and display it like this :

public void drawFrame(Canvas canvas) {
    Position p = movingStrategy.move();
    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);
    matrix.postRotate(p.getRotation());
    matrix.postTranslate(p.getPositionX(), p.getPositionY());
    canvas.drawBitmap(bitmap, matrix, paint);
}

And in my wallpaperservice I am calling the onDraw like this:

 private void draw() {
        handler.removeCallbacks(drawRunner);
        SurfaceHolder holder = getSurfaceHolder();
        Canvas canvas = null;
        try {
            canvas = holder.lockCanvas();
            if (canvas != null) {
                canvas.save();
                canvas.drawColor(Color.BLACK);
                for (DrawElement element : elements) {
                    element.drawFrame(canvas);
                }
                canvas.restore();
            }
        } finally {
            if (canvas != null)
                holder.unlockCanvasAndPost(canvas);
        }
        if (visible) {
            handler.postDelayed(drawRunner, 1);
        }
    }

I tried to use this with a normal View and it's onDraw and there it works fine. It's very smooth. Now I am asking myself how the performance can be improved. I also tried different delayMillis, but the performance doesn't increase.

I have also heard about GLWallpaperService, but this seems very complicated to draw simple Bitmaps. So I want to use Canvas instead.

Thank you

Edit:

I've tested the performance between the view and the service. This part:

  long start = System.currentTimeMillis();
  for (DrawElement element : elements) {
       element.drawFrame(canvas);
  }
  Log.e("DrawingTime", Long.toString(System.currentTimeMillis()-start));

takes in the view 0-1ms and in the service between 50 and 300ms.

user6586661
  • 432
  • 1
  • 11
  • 24

2 Answers2

0

The performance really dependes on how big is your bitmaps, how you allocate and dealocate them, which bitmap config do you use and on which API you run your app.

  1. Keep in mind that big bitmaps is pretty expensive for CPU load and consume a lot of RAM. Try to use exact size as necessary for current screen density and resolution. Avoid allocating useless size that can't be recognized due to device screen limitations.
  2. Reuse your bitmaps if it's possible. Allocationg and deallocating memory for each new bitmap is really heavy operation. If you reuse you bitmaps you can get insane performance increase.
  3. Try to use as low config for your bitmap as possible. Of course if it is some photos it's necessary to keep all color range of them, but even in this case there some configs that allows you to consume twice less memory with almost not visible quality loss.
  4. On some early android versions there are huge proglem with bitmaps because of dalvik specific implementeation. There are no doubts that on 24+ API your app can work better. I'm not saying that you should increase your minimum supported SDK version but anyway you probably should check how it works on all range of supported API's.

Check this usefull stuff:

https://developer.android.com/topic/performance/graphics/ https://developer.android.com/topic/performance/graphics/manage-memory https://developer.android.com/topic/performance/graphics/cache-bitmap

Yazon2006
  • 3,684
  • 3
  • 25
  • 36
0

You should use compressed textures for spites! IE: etc1 & etc2

Using png or jpeg will work, but they use cpu-performance to process and drain the battery quickly.

wulle
  • 1
  • 1
  • Hi Wulle. Welcome to StackOverflow. Short responses like this one should be made as comments. Please see these tips to see what is expected from answers [How to Answer](https://stackoverflow.com/help/how-to-answer). Kind Regards. – Elletlar Dec 07 '20 at 15:20