title: Android Live Wallpaper - why so slow - how to improve speed?
body: <p>I'm attempting to create my first Live Wallpaper. It works and everything would be just fine except of the speed problem. It slows down desktop - widgets and icons are scrolling noticeably slower than when using pro live wallpapers (I'm testing it on Samsung note so there shouldn't be a speed problem). I start thinking that I do it all wrong way- so take a look at my code please:</p>
  
  <pre><code>public class DemoWallpaperService extends WallpaperService {
  
  
  @Override
  public Engine onCreateEngine() {
      return new DemoWallpaperEngine();
  
  }
  
  private class DemoWallpaperEngine extends Engine {
      private boolean mVisible = false;
      private final Handler mHandler = new Handler();
  
       int x=0,y=0,a=255,i=-1, a1=255, i1=-1;
       float r=0,rs=1;
       float rx1=10, rxs=-1;
  
       private Matrix mMatrix = new Matrix();
       private Matrix mMatrix1 = new Matrix();
       private Matrix mMatrixRotate1 = new Matrix();
       private Matrix mMatrixRotate2 = new Matrix();
  
       public Bitmap spaceShip = BitmapFactory.decodeResource(getResources(), R.drawable.spaceship);
       public Bitmap background= BitmapFactory.decodeResource(getResources(), R.drawable.back2short2j);
       public Bitmap wyspa= BitmapFactory.decodeResource(getResources(), R.drawable.wyspa22g);
       public Bitmap ksiezyc = BitmapFactory.decodeResource(getResources(), R.drawable.ksiezyc);
       public Bitmap reflektorfront= BitmapFactory.decodeResource(getResources(), R.drawable.reflektorwyspa);
  
       private float mPixels;
       private float mPixels1;
  
  
  
      private final Runnable mUpdateDisplay = new Runnable() {
      @Override
      public void run() {
          draw();
      }};
  
  
  
      private void draw() {
         SurfaceHolder holder = getSurfaceHolder();
         Canvas c = null;
  
         Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
         int wx= d.getWidth();
         int wy= d.getHeight();
  
  
         try {
             Runtime.getRuntime().gc();
            c = holder.lockCanvas();
            c.save();
  
            if (c != null) {
  
                Paint paintMoon = new Paint();
  
                if(a1&lt;=15){
                    i1=1;
                }
                else if(a1&gt;=255){
                    i1=-1;
                }
                a1+=5*i1;
                paintMoon.setAlpha(a1);
  
                c.translate((float)mPixels, 0f);
                c.drawBitmap(background, mMatrix, null);
                c.drawBitmap(ksiezyc, 1027*wx/480,15*wy/800, paintMoon);
  
                if(rx1&lt;=-15){
                    rxs=1;
                }
                else if(rx1&gt;=15){
                    rxs=-1;
                }
                rx1+=rxs*0.7;
  
                c.translate((float)mPixels1, 0f);
                //reflektor wyspa back
                mMatrixRotate2.setTranslate(340*wx/480,300*wy/800);
                mMatrixRotate2.preRotate(rx1,reflektorfront.getWidth()/2,20);
                c.drawBitmap(reflektorfront, mMatrixRotate2, null);
  
  
                c.drawBitmap(wyspa, mMatrix1, null);
  
                if(r&lt;=-15){
                    rs=1;
                }
                else if(r&gt;=15){
                    rs=-1;
                }
                r+=rs*0.5;
  
  
                mMatrixRotate1.setTranslate(160*wx/480,380*wy/800);
  
                mMatrixRotate1.preRotate(r,reflektorfront.getWidth()/2,20);
  
                c.drawBitmap(reflektorfront, mMatrixRotate1, null);
  
  
                if(x&lt;c.getWidth()){
                x+=3;}
                else{x=0;}
                if(y&lt;c.getHeight()){
                y+=3;}
                else{y=0;}
                Paint paint = new Paint();
  
  
                if(a&lt;=5){
                    i=1;
                }
                else if(a&gt;=255){
                    i=-1;
                }
                a+=10*i;
                paint.setAlpha(a);
  
                c.drawBitmap(spaceShip,x,y,paint);
  
  
                   c.restore();
  
            }
         } finally {
            if (c != null)
               holder.unlockCanvasAndPost(c);
         }
         mHandler.removeCallbacks(mUpdateDisplay);
         if (mVisible) {
             mHandler.postDelayed(mUpdateDisplay, 10);
         }
      }
      @Override
      public void onOffsetsChanged(float xOffset, float yOffset,
               float xStep, float yStep, int xPixels, int yPixels){
  
          super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);                   
           mPixels = xPixels*7/4;
  
           mPixels1 = 500+xPixels;
  
              draw();
      }
  
  
  
      @Override
      public void onVisibilityChanged(boolean visible) {
          mVisible = visible;
          if (visible) {
              draw();
          } else {
              mHandler.removeCallbacks(mUpdateDisplay);
          }
      }
  
       @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  
           super.onSurfaceChanged(holder, format, width, height);
  
           float w = background.getWidth();
           float h = background.getHeight();
           float s = height / (float)h;
           float z = height / (float)h;
           mMatrix.reset();
           mMatrix1.reset();
           mMatrixRotate1.reset();
           mMatrixRotate2.reset();
  
           mMatrix.setScale(s, s);
           mMatrix1.setScale(z, z);
           mMatrixRotate1.setScale(s, s);
  
           draw();
        }
  
      @Override
      public void onSurfaceDestroyed(SurfaceHolder holder) {
          super.onSurfaceDestroyed(holder);
          mVisible = false;
          mHandler.removeCallbacks(mUpdateDisplay);
      }
  
  
      @Override
       public void onCreate(SurfaceHolder surfaceHolder) {
           super.onCreate(surfaceHolder);
  
           setTouchEventsEnabled(false);
       }
  
      @Override
      public void onDestroy() {
           super.onDestroy();
           mVisible = false;
           mHandler.removeCallbacks(mUpdateDisplay);
      }
  }    
  </code></pre>
  
  <p>Basically its a bitmap at background (850x480jpg 70kb), that scrolls slower, bitmap at front (350x400 transparent gif 100 kb) that scrolls faster (to achieve parallax effect) and some smaller png bitmaps (3x 10-20 kb 50x50) that are rotating and moving at the foreground (lights and space ships).</p>
  
  <p>My question is - am I missing the point - I'm animating it by refreshing draw() function with a delay set to 10. (that's the only way I know - should I animate it some other way? Are the bitmaps too big? Or why is it so slow? Should I use sprites to animate front small effects to make it faster? Are there other ways of animating life wallpaper? I went through many tutorials and I've come so far but now I have to ask for help.</p>