将100多个字符串转换为字节数组时的java.lang.OutOfMemoryError

首先,我理解有关java.lang.OutOfMemoryError和Bitmaps的问题,之前已经多次询问过。 我还检查了有效显示位图页面。

我的用例:

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

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

我也使用AsyncTask加载位图。

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

问题

除非我重新启动相同的Activity(例如加载Activity,然后通过在导航抽屉中再次单击它重新创建Activity,然后重复该过程),Activity可以加载大约170个不同的图像而不会发生java.lang.OutOfMemoryError 。 )并在将字符串转换为字节数组时引发了java.lang.OutOfMemoryError

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

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

我的问题简而言之

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

注意

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

我也已在我的Android Manifest中使用android:largeHeap="true"

提前致谢

编辑

以下是我创建Bitmap字符串的方法:

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

我建议你放弃你的方法,这不适用于大量的图像,你已经在你的线程上做了很多工作来处理。 永远不应该在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(); 

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; } 

现在您拥有该文件,现在您只需将文件路径存储在数据库中,当需要时,您始终可以使用滑动从存储中获取文件。 这也可以使您的数据库快速查询。

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