首先,我了解有关java.lang.OutOfMemoryError位图的问题,并且以前已经多次询问过位图。我还签出了“ 有效显示位图”页面。
java.lang.OutOfMemoryError
我的用例:
我将两个不同大小的位图作为字符串存储在SQLite数据库中。位图的第一个大小是屏幕宽度的50%,第二个大小是屏幕宽度的100%。
我使用的是RecyclerView,该图像在ImageViews中显示的图像是屏幕宽度的50%或100%,因此要加载的位图 不会比所需的大,并且在从图像中检索图像之前将它们调整为适当的大小。数据库。
我也正在使用AsyncTask加载位图。
我在RecyclerView中有180多个不同的项,因此总共创建了360多个位图(即numberOfimages * theDifferentSizesOfEachImage)。我通过以下代码将图像的String版本覆盖为字节数组: byte [] byteArray = Base64.decode(encodedString, Base64.DEFAULT);
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。
null
我已经android:largeHeap="true"在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中存储像这样的图像。您只需要将位图转换为具有唯一名称或可以相同(取决于您的用例)的文件,然后就可以将该文件保存在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或其他任何地方进行任何更改。试试这个。