小编典典

将100个以上的字符串转换为字节数组时发生java.lang.OutOfMemoryError

java

首先,我了解有关java.lang.OutOfMemoryError位图的问题,并且以前已经多次询问过位图。我还签出了“
有效显示位图”页面。

我的用例:

我将两个不同大小的位图作为字符串存储在SQLite数据库中。位图的第一个大小是屏幕宽度的50%,第二个大小是屏幕宽度的100%。

我使用的是RecyclerView,该图像在ImageViews中显示的图像是屏幕宽度的50%或100%,因此要加载的位图
不会比所需的大,并且在从图像中检索图像之前将它们调整为适当的大小。数据库。

我也正在使用AsyncTask加载位图。

我在RecyclerView中有180多个不同的项,因此总共创建了360多个位图(即numberOfimages * theDifferentSizesOfEachImage)。我通过以下代码将图像的String版本覆盖为字节数组: byte [] byteArray = Base64.decode(encodedString, Base64.DEFAULT);

问题

活性为能够加载170在围绕不同的图像,而不encurring的java.lang.OutOfMemoryError,除非我重新启动同样的活性(例如加载的活性,然后通过在抽屉式导航再次点击它,然后重复该过程重新创建活动)和所产生的java.lang.OutOfMemoryError,同时将字符串转换为字节数组。

我使用以下代码使用 Glide 库将字节数组转换为位图:

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

简而言之,我的问题

java.lang.OutOfMemoryError在将字符串转换为字节数组时,如何避免发生这种情况?

注意

使用Glide创建位图后,我在给定的位图上调用recycle(),然后将其设置为null

我已经android:largeHeap="true"在Android清单中使用了

提前致谢

编辑

这是我创建位图字符串的方法:

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

阅读 386

收藏
2020-11-30

共1个答案

小编典典

我建议您放弃的方法,这将不适用于大量图像,并且您已经在线程上进行了大量工作来处理。永远不要在sqllite中存储像这样的图像。您只需要将位图转换为具有唯一名称或可以相同(取决于您的用例)的文件,然后就可以将该文件保存在app目录中,并将文件路径保存在数据库中。这里有一些代码可以帮助您。

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();

私有文件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;
}

现在您已经有了文件,现在您可以将文件路径存储在数据库中,并且在需要时始终可以使用glide从存储中获取文件。这也将使您的数据库快速查询。

这样,您就不需要在gradle或其他任何地方进行任何更改。试试这个。

2020-11-30