Live Wallpaper + bitmap + canvas

2019-09-06 12:47发布

问题:

Helo everyone! I have this live wallpaper in witch I try to show a bitmap trough a canvas (the drawable resource is a 400k 1900x1200 jpg). It force-closes and I don't get why (it's my first Android project). These are the "important" bits:

    wallEngine() { // CONSTRUCTOR   <<<<<<<<<<<<<<<<<<<
                            mStartTime = SystemClock.elapsedRealtime();


                            Log.v(Logcat, "Contructor ok");

                        }
                //====================================== INIT
                        private final Runnable mDrawWall = new Runnable() { //=========== RUN
                            public void run() {
                                drawFrame();
                            }
                        };

   void drawFrame() {

                           final SurfaceHolder holder = getSurfaceHolder();                                         
                           Canvas c = null;
                           try {
                                c = holder.lockCanvas();
                                if (c != null) {
                                    // draw something
                                    updatePhysics();
                                    doDraw(c);
                                }
                            } finally {
                                if (c != null) holder.unlockCanvasAndPost(c);
                            }

                            // Reschedule the next redraw
                            mHandler.removeCallbacks(mDrawWall);
                            if (mVisible) {
                                mHandler.postDelayed(mDrawWall, 5000);
                            }
                        }


    private void doDraw(Canvas canvas) {                                                                                    
                      //backgroundImage.prepareToDraw();                                                    
                    canvas.drawBitmap(this.backgroundImage, 0, 0, null);                                                                    
                        }


public void onCreate(SurfaceHolder surfaceHolder) {

                            super.onCreate(surfaceHolder);                      surfaceHolder.setFormat(android.graphics.PixelFormat.RGBA_8888);        

                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inPurgeable = true;

                            this.backgroundImage = BitmapFactory.decodeResource(getResources(), 
                                com.misca.livewallpapers.parang.R.drawable.a, options);

                            //backgroundImage.prepareToDraw();
                            //setTouchEventsEnabled(true);
                            Log.v(Logcat, "onCreate ok");
                        }

And the logcat errors when i try to run it on my phone are :

ERROR/AndroidRuntime(7722): FATAL EXCEPTION: main
ERROR/AndroidRuntime(7722): java.lang.NullPointerException
ERROR/AndroidRuntime(7722):     at android.graphics.Canvas.throwIfRecycled(Canvas.java:957)
ERROR/AndroidRuntime(7722):     at android.graphics.Canvas.drawBitmap(Canvas.java:983)
ERROR/AndroidRuntime(7722):     at com.misca.livewallpapers.parang.liveWallpaper$wallEngine.doDraw(liveWallpaper.java:115)
ERROR/AndroidRuntime(7722):     at com.misca.livewallpapers.parang.liveWallpaper$wallEngine.drawFrame(liveWallpaper.java:75)
ERROR/AndroidRuntime(7722):     at com.misca.livewallpapers.parang.liveWallpaper$wallEngine.onSurfaceChanged(liveWallpaper.java:157)
ERROR/AndroidRuntime(7722):     at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:590)
ERROR/AndroidRuntime(7722):     at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:654)
ERROR/AndroidRuntime(7722):     at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:878)
ERROR/AndroidRuntime(7722):     at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61)
ERROR/AndroidRuntime(7722):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(7722):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(7722):     at android.app.ActivityThread.main(ActivityThread.java:3848)
ERROR/AndroidRuntime(7722):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(7722):     at java.lang.reflect.Method.invoke(Method.java:507)
ERROR/AndroidRuntime(7722):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
ERROR/AndroidRuntime(7722):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
03-23 00:26:42.309: ERROR/AndroidRuntime(7722):     at dalvik.system.NativeStart.main(Native Method)

Thank you! :)

======================= News:

                        private void doDraw(Canvas canvas) {                                                                               
                        //backgroundImage.prepareToDraw();                         
                        if(this.backgroundImage!=null)
                        canvas.drawBitmap(this.backgroundImage, 0, 0, null);
                        else
                        Log.v(Logcat, "null");

                    }

And seems the bitmap is null. Now i'm working with a 480x800 to ensure there are no memory problems. The app doesn't crash anymore with the if statement (empty black screen)

回答1:

Have you tried scaling the bitmap to fit the canvas? Do this in onSurfaceChanged, so you'll know the width and height to use. You should check that your bitmap is being decoded correctly. It doesn't matter that your resource is 400K--that's a very big bitmap to try to load into memory. You only have 16 meg of heap...that bitmap is about 9 meg (4 bytes/pixel ARGB_8888). George