Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将超过100个字符串转换为字节数组时发生java.lang.OutOfMemoryError_Java_Android_Out Of Memory_Bytearray_Android Glide - Fatal编程技术网

将超过100个字符串转换为字节数组时发生java.lang.OutOfMemoryError

将超过100个字符串转换为字节数组时发生java.lang.OutOfMemoryError,java,android,out-of-memory,bytearray,android-glide,Java,Android,Out Of Memory,Bytearray,Android Glide,首先,我了解关于java.lang.OutOfMemoryError和位图的问题,以前已经问过很多次了。我还签出了页面 我的用例: 我将两个不同大小的位图作为字符串存储在SQLite数据库中。位图的第一个大小是屏幕宽度的50%,第二个大小是屏幕宽度的100% 我正在使用一个RecyclerView,它在ImageView中显示屏幕宽度的50%或100%的图像,因此加载的位图不会比需要的大,并且在从数据库检索图像之前大小适当。 我还使用异步任务加载位图 我在RecyclerView中有180多个不

首先,我了解关于
java.lang.OutOfMemoryError
和位图的问题,以前已经问过很多次了。我还签出了页面

我的用例:


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

我正在使用一个RecyclerView,它在ImageView中显示屏幕宽度的50%或100%的图像,因此加载的位图不会比需要的大,并且在从数据库检索图像之前大小适当。

我还使用异步任务加载位图

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

问题

该活动能够加载大约170个不同的图像,而不会出现
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清单中使用了
android:largeHeap=“true”

提前谢谢

编辑

以下是我如何创建位图字符串:

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

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

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(上下文,int m){

现在你有了文件,现在你可以将文件路径存储在数据库中,当需要时,你可以使用glide从存储中获取文件。这也可以使数据库快速进行查询


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

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

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(上下文,int m){

现在你有了文件,现在你可以将文件路径存储在数据库中,当需要时,你可以使用glide从存储中获取文件。这也可以使数据库快速进行查询


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

为什么不在存储之前压缩它…谢谢您的回答。如果您指的是压缩位图,我已经在这样做了,我编辑了我的问题,您可以看到在将位图转换为字符串之前我是如何压缩位图的“我将两个不同大小的位图作为字符串存储在SQLite数据库中"--为什么?将它们存储为文件,并在数据库中使用文件名。或者,将它们存储为BLOB列,以至少消除
字符串
转换。感谢您的响应。我正在存储两种不同大小的位图,因为我使用两种不同大小的图像。是否将它们存储为文件并在数据库中存储文件名,或者将图像存储在BLOB列中有助于避免
java.lang.OutOfMemoryError
。如果这两个选项都有助于避免
java.lang.OutOfMemoryError
,那么哪个选项的内存效率最高?为什么不在存储它之前先压缩它呢?谢谢你的回答。如果你指的是压缩位图,我已经读过了我正在这样做,我编辑了我的问题,你可以看到我在将位图转换为字符串之前是如何压缩的“我正在将两个不同大小的位图作为字符串存储在SQLite数据库中”--为什么?将它们存储为文件,并在数据库中使用文件名。或者,将它们存储为BLOB列,以至少消除
字符串
转换。感谢您的响应。我正在存储两种不同大小的位图,因为我使用两种不同大小的图像。是否将它们存储为文件并在数据库中存储文件名,或者在BLOB列中保存图像有助于避免
java.lang.OutOfMemoryError
。如果这两个选项都有助于避免
java.lang.OutOfMemoryError
,那么哪个选项的内存效率最高?感谢您的回复。如果可以解决
java.lang.OutO>问题,我将尝试将图像保存为字节数组文件fMemoryError
。您认为将图像保存为文件,然后将文件转换为图像比将图像保存为字节数组更节省内存吗