1

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 !!

1 Answer 1

2

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
    }
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. I would definitely try it. Btw why would a ViewTreeObserver work?
Because you are trying to get layout size before the layout has been computed (i.e. you still don't know the dimensions because Android has still not computed them). ViewTreeObserver allows you to receive a callback when this happens: "A view tree observer is used to register listeners that can be notified of global changes in the view tree. Such global events include, but are not limited to, layout of the whole tree, beginning of the drawing pass, touch mode change.... " developer.android.com/reference/android/view/…
BTW I've edited the answer to fix a few variable name mistakes.
Thnx for the reply, will try it and accept it if this works thanks a lot !!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.