将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或其他任何地方进行任何更改。 尝试这个。