Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
550 views
in Technique[技术] by (71.8m points)

android - java.lang.IllegalStateException: Can't compress a recycled bitmap in OnPostExecute ( ) method

I've got a "Can't compress a recycled bitmap error" in my app. It happened on the bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);

 class QRLoad extends AsyncTask<Void, Void, Bitmap> {

    private Context context;
    private String photo;

    public QRLoad(Context context, String photo) {
        this.context = context;
        this.photo = photo;
    }

    @Override
    protected Bitmap doInBackground(Void... voids) {
        Log.e(TAG, "Constants.QR_BASE_URL photo:" + Constants.QR_BASE_URL + photo);
        Bitmap bitmap = null;
        try {
            bitmap = Glide.with(context)
                    .asBitmap()
                    .load(Constants.QR_BASE_URL + photo)
                    .submit()
                    .get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null)
            convertQRBitmapToByte(bitmap);
        else
            Log.e(TAG, "QR bitmap is null");
    }

}
private void convertQRBitmapToByte(Bitmap bitmap) {
    Bitmap bmp = bitmap;
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] byteArray = stream.toByteArray();
    bmp.recycle();

    appDataBase = AppDataBase.getAppDatabase(context);
    appDataBase.userDao().updateQRPhoto(
            Constants.getRoomDBUserInfo(context).getPocket_mobileno(),
            byteArray);
}

Bellow is the error Should I check null value . but is occurs in first time when app lunch but second time its all ok .or should I use handeler to post delay

2021-01-24 12:48:22.356 28951-28951/net.uumoo.drawer.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: net.uumoo.drawer.android, PID: 28951
    java.lang.IllegalStateException: Can't compress a recycled bitmap
        at android.graphics.Bitmap.checkRecycled(Bitmap.java:391)
        at android.graphics.Bitmap.compress(Bitmap.java:1335)
        at net.uumoo.drawer.main.LandingPage.view.LandingDrawerActivity.c(:742)
        at net.uumoo.drawer.main.LandingPage.view.LandingDrawerActivity.b(:114)
        at net.uumoo.drawer.main.LandingPage.view.LandingDrawerActivity$c.a(:816)
        at net.uumoo.drawer.main.LandingPage.view.LandingDrawerActivity$c.onPostExecute(:785)
        at android.os.AsyncTask.finish(AsyncTask.java:695)
        at android.os.AsyncTask.access$600(AsyncTask.java:180)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:198)
        at android.app.ActivityThread.main(ActivityThread.java:6729)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
question from:https://stackoverflow.com/questions/65867920/java-lang-illegalstateexception-cant-compress-a-recycled-bitmap-in-onpostexecu

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Do you really need to return the bitmap as all you do is write it to the DB? I would suggest that you could return only the byteArray. So your class should look like this: class QRLoad extends AsyncTask<Void, Void, byte[]>. Also appDataBase = AppDataBase.getAppDatabase(context); could cause an exception if the device is rotated during the doInBackground method. I would suggest that your class looks like this:

class QRLoad extends AsyncTask<Void, Void, byte[]> {

    private WeakReference<Context> contextWeakReference;
    private String                 photo;

    public QRLoad(Context context, String photo) {
        this.contextWeakReference = new WeakReference<>(context);
        this.photo = photo;
    }

    @Override
    protected byte[] doInBackground(Void... voids) {
        Log.e(TAG, "Constants.QR_BASE_URL photo:" + Constants.QR_BASE_URL + photo);
        try {
            Context context = contextWeakReference.get();
            if (context == null) {
                return null;
            }
            Bitmap bitmap = Glide.with(context)
                          .asBitmap()
                          .load(Constants.QR_BASE_URL + photo)
                          .submit()
                          .get();

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            bitmap.recycle();
            return byteArray;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(byte[] bytes) {
        if (bytes != null)
            saveToDb(bytes);
        else
            Log.e(TAG, "QR bitmap is null");
    }
    private void saveToDb(byte[] bytes) {
        Context context = contextWeakReference.get();
        if (context == null) {
            return;
        }
        appDataBase = AppDataBase.getAppDatabase(context);
        appDataBase.userDao().updateQRPhoto(
            Constants.getRoomDBUserInfo(context).getPocket_mobileno(),
            bytes);
    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...