java.lang.OutOfMemoryError:使用BitmapFactory.decodeByteArray为RecyclerView创建预先设定大小的位图时

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

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

我的用例:

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

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

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

我在RecyclerView中有12个不同的项目,因此我总共有24个位图(12个图像,2种大小)通过以下代码创建:
BitmapFactory.decodeByteArray(encodeByte,0,encodeByte.length)

问题

加载活动时不带
java.lang.OutOfMemoryError
,除非我连续5次重新启动同一活动(例如,加载活动,然后通过在导航抽屉中再次单击该活动,然后重复该过程来重新创建活动)

可能的解决方案

如果我在onPause生命周期事件中循环使用位图,如下所示:

public void recycleBitmaps(){
    int howManyBitmaps = bitmapsFullScreenWidth.size();
    for (int i = 0; i < howManyBitmaps; i++) {
        if (recyclerAdapter.bitmapsHalfScreenWidthArrayList.get(i) != null && !recyclerAdapter.bitmapsHalfScreenWidthArrayList.get(i).isRecycled()) {
            recyclerAdapter.bitmapsHalfScreenWidthArrayList.get(i).recycle();
            recyclerAdapter.bitmapsHalfScreenWidthArrayList.remove(i);
            recyclerAdapter.bitmapsHalfScreenWidthArrayList.add(i, null);
        }
    }


    for (int i = 0; i < howManyBitmaps; i++) {
        if (recyclerAdapter.bitmapsFullScreenWidth.get(i) != null && !  recyclerAdapter.bitmapsFullScreenWidth.get(i).isRecycled()) {
            recyclerAdapter.bitmapsFullScreenWidth.get(i).recycle();
            recyclerAdapter.bitmapsFullScreenWidth.remove(i);
            recyclerAdapter.bitmapsFullScreenWidth.add(i, null);
        }

    }
}
public void recyclebitmap(){
int howmanybitmap=bitmapsFullScreenWidth.size();
for(int i=0;i
然后,
java.lang.OutOfMemoryError
不会发生,但我必须在
onResume()中初始化RecylerView的适配器
为了避免出现
画布:尝试使用回收的位图android.graphics。
错误,这意味着如果用户在进行此活动时离开应用程序,则必须在重新进入该活动后重新初始化适配器,最好是在每次调用onPause()时都不循环位图的情况下解决
java.lang.OutOfMemoryError

我不愿意缓存位图,因为这可能会使活动的其余部分执行得不太顺利

我的问题简而言之

如果我的活动能够成功加载位图而不会因java.lang.OutOfMemoryError而崩溃,直到我多次重新启动活动,那么当我的活动多次重新启动时,避免
java.lang.OutOfMemoryError
的最佳方法是什么

提前谢谢


编辑Glide库能够解决OOM问题,但它会导致RecyclerView的一些图像在RecyFileView滚动时消失,尽管它们被重新加载-但这可能是可以解决的

从您所说的,听起来您实际上在设置新位图,而旧位图仍在内存中。我不完全清楚您为什么不愿意缓存位图。真的没有别的办法了。如果在位图从缓存解码时显示加载图像(如有必要),则不会出现性能问题。不管怎样,我希望你使用的是图书馆。如果您使用Universal Image Loader或毕加索,这个问题会得到很好的解决。谢谢您的回复。我不认为通用图像加载器或毕加索能够加载字节数组,如果我可以使用其中一个来加载字节数组,那么我会这样做。它说缓存“位图是以占用宝贵的应用程序内存为代价的”,但是,如果它不会影响我在该活动中的动画性能,那么如果没有更简单的方法来避免您所说的OOM错误,我可能会缓存位图。听起来您实际上正在设置新位图,而旧位图仍在内存中。我不完全清楚您为什么不愿意缓存位图。真的没有别的办法了。如果在位图从缓存解码时显示加载图像(如有必要),则不会出现性能问题。不管怎样,我希望你使用的是图书馆。如果您使用Universal Image Loader或毕加索,这个问题会得到很好的解决。谢谢您的回复。我不认为通用图像加载器或毕加索能够加载字节数组,如果我可以使用其中一个来加载字节数组,那么我会这样做。它说缓存“位图是以占用宝贵的应用程序内存为代价的”,但是,如果它不会影响我在该活动中的动画性能,那么如果没有更简单的方法来避免OOM错误,我可能会缓存位图