2
votes

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.marsad.wallpaperapp, PID: 20425 java.lang.ArithmeticException: divide by zero

Hi, When I click on gif image to apply as live wallpaper mostly everything works good but sometime app crash with the error

Logcat

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.marsad.wallpaperapp, PID: 20425 java.lang.ArithmeticException: divide by zero at com.marsad.wallpaperapp.GIFWallpaperService$GIFWallpaperEngine.draw(GIFWallpaperService.java:139) at com.marsad.wallpaperapp.GIFWallpaperService$GIFWallpaperEngine.access$000(GIFWallpaperService.java:82) at com.marsad.wallpaperapp.GIFWallpaperService$GIFWallpaperEngine$1.run(GIFWallpaperService.java:111) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:7139) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)

Here is the full code


public class GIFWallpaperService extends WallpaperService {
    Context context;


    @Override
    public WallpaperService.Engine onCreateEngine() {

        Singleton b = Singleton.getInstance();
        String path = b.getPath();


        try {
            InputStream is = new FileInputStream(path);
            Movie movie = Movie.decodeStream(is);

            return new GIFWallpaperEngine(movie);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            return null;
        }
        

    }


    private class GIFWallpaperEngine extends WallpaperService.Engine {

        private final int frameDuration = 20;
        private SurfaceHolder holder;
        private Movie movie;
        private boolean visible;
        private Handler handler;

        int width;
        int height;

        public GIFWallpaperEngine(Movie movie) {

            this.movie = movie;
            handler = new Handler();

        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);

            this.holder = surfaceHolder;

        }

        private Runnable drawGIF = new Runnable() {
            @Override
            public void run() {
                draw();
            }
        };

        private void draw() {

            WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            float screenWidth = display.getWidth();
            float screenHeight = display.getHeight();

            width = (int) screenWidth;
            height = (int) screenHeight;


            if (visible) {
                Canvas canvas = holder.lockCanvas();
                canvas.save();


                canvas.scale((float) display.getWidth() / (float) movie.width(),
                        (float) display.getHeight() / (float) movie.height());
                movie.draw(canvas, 0, 0);


                canvas.restore();

                holder.unlockCanvasAndPost(canvas);
                movie.setTime((int) (System.currentTimeMillis() % movie.duration()));

                handler.removeCallbacks(drawGIF);
                handler.postDelayed(drawGIF, frameDuration);

            }

        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            //super.onVisibilityChanged(visible);

            this.visible = visible;

            if (visible) {
                handler.post(drawGIF);
            } else {
                handler.removeCallbacks(drawGIF);
            }


        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            this.visible = false;
            handler.removeCallbacks(drawGIF);
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format,
                                     int width, int height) {
            this.width = width;
            this.height = height;
            super.onSurfaceChanged(holder, format, width, height);
        }
        

        @Override
        public void onDestroy() {
            super.onDestroy();
            handler.removeCallbacks(drawGIF);

        }


    }

}

2
Line 139 of GIFWallpaperService.java has a statement that is doing / division or % remainder, and the divisor is zero. Which part of that is confusing? How you need to figure out why the divisor is zero, but only you can do that, because only you have the data in question. - Andreas

2 Answers

3
votes

You may check before draw like this

if(movie.width() > 0 && movie.height() > 0){
        canvas.scale((float) display.getWidth() / (float) movie.width(),
                (float) display.getHeight() / (float) movie.height());
        movie.draw(canvas, 0, 0);
}else{
        //do something default which suit your application
}
2
votes

Your exception is coming from these lines:

            canvas.scale((float) display.getWidth() / (float) movie.width(),
                    (float) display.getHeight() / (float) movie.height());
            movie.draw(canvas, 0, 0);

And not the ones you mentioned.

Since these lines are the ones where division by zero might happen.

I would make sure that the movie object has a width/height before doing the calculation.