java.lang.OutOfMemoryError while converting over 100 Strings into to byte arrays

99封情书 提交于 2019-12-02 19:31:27

问题


Firstly, I understand questions regarding java.lang.OutOfMemoryError and Bitmaps have already been asked numerous times before. I have also checked out the Displaying Bitmaps Efficiently page.

My use case:

I am storing two different sized Bitmaps as Strings in an SQLite database. The first size of the Bitmaps is 50% of the screen width, and the second size is 100% of the screen width.

I am using a RecyclerView which displays the images in ImageViews which are either 50% or 100% of the screen width, so the Bitmaps being loaded are no bigger than they need to be, and they are appropriately sized before the images are retrieved from the Database.

I am also loading the Bitmaps using an AsyncTask.

I have over 180 different items in the RecyclerView so I have a total of over 360 Bitmaps (i.e. numberOfimages * theDifferentSizesOfEachImage) being created. I am coverting the String versions of the images into byte arrays via this code: byte [] byteArray = Base64.decode(encodedString, Base64.DEFAULT);

The Problem

The Activity was able to load over around 170 different images without encurring the java.lang.OutOfMemoryError, unless I restarted the same Activity (e.g. load the Activity, then recreate the Activity by clicking on it again in the Navigation Drawer and then repeating that process) and incurred the java.lang.OutOfMemoryError whilst converting the Strings into byte arrays.

I am converting the byte array to a Bitmap using the Glide library using the following code:

 Bitmap bitmap = Glide.with(context).load(byteArray).asBitmap()
 .dontTransform().dontAnimate().skipMemoryCache(true)
 .diskCacheStrategy(DiskCacheStrategy.NONE).into(-1, -1).get();

My Question in a nutshell

How do I avoid the java.lang.OutOfMemoryError occurring whilst am I converting the Strings into byte arrays?

Note

After creating a Bitmap using Glide I am calling recycle() on the given Bitmap and then setting it to null.

I am also already using android:largeHeap="true" in my Android Manifest

Thanks in advance

Edit

Here is how I am creating the Bitmap Strings:

 ByteArrayOutputStream baos = new  ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.WEBP,100, baos);
        byte [] b =baos.toByteArray();
     String bitmapString = Base64.encodeToString(b, Base64.DEFAULT);

回答1:


What i would suggest you to drop your approach, this would just not work with large set of image and you are already putting to much work on your thread to handle. One should never store image like that in the sqllite. You should just convert your bitmap to a file having unique name or could be same (depends upon your use case) then you can just save this file inside the app directory and save the file path in database. Here is some code to help you.

File pictureFile = getOutputMediaFile(getActivity(), MEDIA_TYPE_IMAGE);
        if (pictureFile == null) {
            return;
        }
        Bitmap bitmap =BitmapFactory.decodeByteArray(data,0,data.length);

            FileOutputStream fos = new FileOutputStream(pictureFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();

private File getOutputMediaFile(Context context, int m) {

    File mediaStorageDir = context.getFilesDir();

    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d("Fade", "failed to create directory");
            return null;
        }
    }
    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
            .format(new Date());

    File mediaFile=new File(mediaStorageDir.getPath()+File.separator
                + "IMG_" + timeStamp + ".JPG");

    return mediaFile;
}

Now you have the file and now you can just store the file path in the database and when its needed you can always get your file from the storage using glide. This would also make your database fast to queries.

This way you wont need any changes in gradle or anywhere else. Try this.



来源:https://stackoverflow.com/questions/38030770/java-lang-outofmemoryerror-while-converting-over-100-strings-into-to-byte-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!