varunkr
varunkr

Reputation: 5552

java.lang.IllegalArgumentException: width and height must be > 0

I have an app on playstore that generates the following error on very few devices.

java.lang.IllegalArgumentException: width and height must be > 0
    at android.graphics.Bitmap.createBitmap(Bitmap.java:829)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:808)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:775)
    at com.my.app.fragments.ImageFragment$MyAsyncTask$1.void run()(SourceFile:209)
    at android.os.Handler.handleCallback(Handler.java:745)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:171)
    at android.app.ActivityThread.main(ActivityThread.java:5454)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)

The error occurs on this line in onPostExecute in MyAsyncTask

c.drawBitmap(Bitmap.createBitmap(linearLayout.getWidth(), linearLayout.getHeight(), Bitmap.Config.RGB_565), 0, 0, p);

This is my code

In my ImageFragment in onCreateView I do this

    ImageView img = (ImageView) rootView.findViewById(R.id.img);
    final LinearLayout view= (LinearLayout) rootView.findViewById(R.id.view);
    MyAsyncTask asyncTask= new MyAsyncTask(img, view);
    asyncTask.execute(number);

Then in AsyncTask

class MyAsyncTask extends AsyncTask<Integer, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;
        private LinearLayout linearLayout;

        public MyAsyncTask(ImageView imageView, LinearLayout linearLayout) {
            imageViewReference = new WeakReference<>(imageView);
            this.linearLayout = linearLayout;
        }

        // Decode image in background.
        @Override
        protected Bitmap doInBackground(Integer... params) {

            // Code skipped
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                    blurred = CommonUtils.fastblur(bitmap, 0.2f, 20);
                    final Bitmap resultBitmap = Bitmap.createBitmap(blurred.getWidth(), blurred.getHeight(), Bitmap.Config.ARGB_8888);

                    final Canvas c = new Canvas(resultBitmap);
                    c.drawBitmap(blurred, 0, 0, null);

                    final Paint p = new Paint();
                    p.setAlpha(127);

                    linearLayout.post(new Runnable() {
                        @Override
                        public void run() {
                            c.drawBitmap(Bitmap.createBitmap(linearLayout.getWidth(), linearLayout.getHeight(), Bitmap.Config.RGB_565), 0, 0, p);
                            // Rest code skipped
                        }
                    });
                }
            }
        }
    }

After reading many stackoverflow posts on this problem I found that this occurs if the view is not yet ready and hence it should be used with the View's post method with your own runnable. But I can't understand why it is still causing this error on some devices namely Samsung. Does someone have an idea how this can be fixed? Any suggestion would be appreciated. Thanks !!

Upvotes: 1

Views: 4045

Answers (1)

Xavier Rubio Jansana
Xavier Rubio Jansana

Reputation: 6583

Your task is running too fast on this devices and the LinearLayout has still not been layout. You can use a ViewTreeObserver:

ViewTreeObserver vto = linearLayout.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
        linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        int width  = linearLayout.getMeasuredWidth();
        int height = linearLayout.getMeasuredHeight(); 
        c.drawBitmap(Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565), 0, 0, p);
        // Rest code skipped
    }
});

Upvotes: 2

Related Questions