'Android: Drawing a bitmap on a hardware-accelerated canvas yields corrupted display, odd behavior

I've been stuck for several days on drawing to a hardware-accelerated canvas from a live wallpaper.

When the wallpaper launches, it's in portrait mode and everything initially looks OK: HW canvas: upright

When I rotate the phone, the left half of the screen contains the image and the right half of the screen is black: HW canvas: rotated

Then, when I rotate back to the original orientation, it gets weirder. HW canvas: back to upright

Drawing on a non-accelerated canvas works fine. Just change lockHardwareCanvas in the code below to lockCanvas. Software canvas: upright - Software canvas: rotated

Sample code:

package reproduceproblem

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Rect
import android.service.wallpaper.WallpaperService
import android.util.DisplayMetrics
import android.view.SurfaceHolder
import android.view.WindowManager

class MyWallpaperService: WallpaperService() {
   override fun onCreateEngine(): Engine = WallpaperEngine()

   inner class WallpaperEngine : WallpaperService.Engine() {
      override fun onSurfaceChanged(
         holder: SurfaceHolder,
         format: Int,
         width: Int,
         height: Int
      ) {
         super.onSurfaceChanged(holder, format, width, height)

         val bmp: Bitmap = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.webb)
         val rect = Rect( 0, 0, width, height )
         val canvas: Canvas = holder.lockHardwareCanvas()

         canvas.drawBitmap(bmp, null, rect, null)
         holder.unlockCanvasAndPost(canvas)
      }
   }
}


Solution 1:[1]

I never figured out why this was happening, but I solved it very quickly by using libgdx. Make sure to create a new SpriteBatch on device rotation, because SpriteBatch internally sets its own width and height, and it doesn't update once created.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 protochicken