I would like to ask about a problem that was examined here once or twice, but none of the information found helped me overcome the problem that I encountered a few days ago.
I want to make live wallpapers for android using canvases - it is not graphically complex enough to require OpenGL. For simplicity, suppose it consists of a solid background and two smaller rectangles. Drawing consists of three separate stages (in one thread):
- backgroundDraw () requests locking the entire canvas and draws a solid color on it
- draw1 () requires a partial (Rect r1) lock and draws only on a locked rectangle
- draw2 () requires a partial (Rect r2) lock and draws only on a locked rectangle
I tested it on several versions of Android (both emulators and devices): 2.1, 2.2, 2.3.3. It seems that it only works correctly on the latter (here: http://home.elka.pw.edu.pl/~pgawron/include/Android/android_233.jpg ). In previous versions of Android, SurfaceHolder.lockCanvas (Rect dirty) is resized (!) Dirty, passed as a parameter to the size of full-screen and subsequent drawing, using it, displays the picture in full screen (here: http://home.elka.pw.edu .pl / ~ pgawron / include / Android / android_22.jpg ). In fact, I see how each rectangle is poorly drawn (full screen): the entire screen changes color very quickly.
False, Google could not find a suitable example for me using lockCanvas (Rect dirty). Below I enclose my complete and only class used for testing. A full eclipse project is only available where screenshots are posted.
I would be extremely grateful if anyone could finally help me and fix my code (if only the problem is in my code). I really spent too much time on this.
BR
Petrelli
package sec.polishcode.test; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.SystemClock; import android.service.wallpaper.WallpaperService; import android.util.Log; import android.view.SurfaceHolder; public class TestLiveWallpaper extends WallpaperService{ @Override public Engine onCreateEngine() { return new MyEngine(); } class MyEngine extends Engine implements SurfaceHolder.Callback { private final String LOGTAG = MyEngine.class.getSimpleName(); private Paint backgroundPaint = new Paint(); private Paint mPaint1 = new Paint(); private Paint mPaint2 = new Paint(); private long lastVisibilityOnChange; private final Rect r1 = new Rect(20, 20, 60, 280); private final Rect r2 = new Rect(70, 20, 110, 280); public MyEngine() { getSurfaceHolder().addCallback(this); backgroundPaint.setColor(Color.YELLOW); mPaint1.setColor(Color.LTGRAY); mPaint2.setColor(Color.MAGENTA); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { drawSurface(); } @Override public void surfaceCreated(SurfaceHolder arg0) { Log.i(LOGTAG, "surfaceCreated"); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { Log.i(LOGTAG, "surfaceDestroyed"); } @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); setTouchEventsEnabled(true); } @Override public void onVisibilityChanged(boolean visible) { if (!visible) return; lastVisibilityOnChange = SystemClock.elapsedRealtime(); drawSurface(); } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) { if (SystemClock.elapsedRealtime() - lastVisibilityOnChange > 30) return; Log.i(LOGTAG, "onOffsetsChanged filtered"); drawSurface(); } private void drawSurface() { backgroundDraw(); draw1(); draw2(); } private void backgroundDraw() { final SurfaceHolder holder = getSurfaceHolder(); Canvas c = null; try { c = holder.lockCanvas(); if (c != null) { c.drawRect(holder.getSurfaceFrame(), backgroundPaint); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } } private void draw1() { final SurfaceHolder holder = getSurfaceHolder(); Canvas c = null; try { c = holder.lockCanvas(r1); if (c != null) { c.drawRect(r1, mPaint1); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } } private void draw2() { final SurfaceHolder holder = getSurfaceHolder(); Canvas c = null; try { c = holder.lockCanvas(r2); if (c != null) { c.drawRect(r2, mPaint2); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } } } }