Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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
Android 跟踪我的OOM错误(内存不足)_Android_Out Of Memory_Android Glide - Fatal编程技术网

Android 跟踪我的OOM错误(内存不足)

Android 跟踪我的OOM错误(内存不足),android,out-of-memory,android-glide,Android,Out Of Memory,Android Glide,所以我对我的问题有一些理论,但我读到一些相互矛盾的信息,这让我的处境有点困惑 要从顶层视图概述我的问题,请执行以下操作: 我有一个标签布局中有3个片段的应用程序。第一个(显示在应用程序加载中)包含一个RecyclerView。每个ViewHolder包含一行TextView和3个imagebutton,所有这些按钮都具有从存储在/drawable nodpi文件夹中的小型(100-300kb)jpg图像加载的背景纹理。图像按钮还有一个额外的小(1kb).png,显示在这些纹理的顶部 在主活动的R

所以我对我的问题有一些理论,但我读到一些相互矛盾的信息,这让我的处境有点困惑

要从顶层视图概述我的问题,请执行以下操作:

我有一个标签布局中有3个
片段的应用程序。第一个(显示在应用程序加载中)包含一个
RecyclerView
。每个
ViewHolder
包含一行
TextView
和3个
imagebutton
,所有这些按钮都具有从存储在
/drawable nodpi
文件夹中的小型(100-300kb)jpg
图像加载的背景纹理。图像按钮还有一个额外的小(1kb)
.png
,显示在这些纹理的顶部

在主活动的
RecyclerView
ImageButton
s之间,图像总量约为6MB,应用程序最终必须在启动时加载

分别而言,该应用程序在最新的API或一般较新的手机上运行良好。该应用程序在
API23
和bellow范围内容易出现斑点。一些
API23
手机可以工作,但是一些手机由于各种原因而崩溃。我意识到每次崩溃都可能有许多不同的原因,因此对于这个问题,我将重点关注著名的
内存不足错误。我确实有一部物理API 23手机,我一直在尝试使用android studio对其进行评测,内存如下所示:

到目前为止,这支持这样一种观点,即至少在这个使用API 23的手机上,我遇到了图形渲染问题,可能是图像加载?虽然我的堆转储和内存分析不起作用,但我无法获得特定的运行任务

关于图像渲染 这就是我困惑的地方。本案例中的大多数在线信息都指向使用Glide、毕加索或Facebook自己的壁画等图书馆。然而,我也看到了其他相关帖子中的评论,所以像我这样从Drawables文件夹加载图像的人不需要使用这些库。(尤其是当我的图像与gallery应用程序中的图像相比非常小时,每张图像的容量可能达到1 MB。)

然而,网上铺天盖地的信息表明,这可以通过图书馆来解决,所以我的问题是:可以吗?或者我的问题在其他地方,可能在我的片段代码中,或者在我的适配器中,等等

我将从我的图像开始:

/src/main/res

  • 可牵引/

    • .png(平均1kb左右,小于100x100像素)这些是前景可绘制图像
  • 可拉伸节点/

    • .jpg纹理(平均值分别为100-300kb、1200x1500px和3000x2000px)也许这就是我可以节省内存的地方

现在我想在这里发布我的代码,但我似乎不知道,因为我的问题是我上面的图片,更多关于这一点在我的后续回答。我还利用Glide进行了一些更改,并实现了一些更改,但将当前的逻辑迁移到不同的映像加载结构很快就成为了一个巨大的挑战。

我的第一次尝试是将映像逻辑切换到适配器中。请注意,这些
imagebutton
最初是通过分配给xml布局中的background属性来加载的。这涉及到在我的一些模型逻辑(归因于这些按钮)中来回移动,并在片段和适配器之间来回传递信息

结果看起来像这样:

公共类MyFragment扩展了片段{
...
@凌驾
已创建公用void onview(@NonNull视图,Bundle savedInstanceState){
//在此处初始化数据
mAdapter=新的傻瓜适配器(mfooList,getContext());//{
//改变模式
//用Glide加载新图像
//在片段中更新模型
}
//设置按钮侦听器
}
}
虽然我的按钮和模型有很多变化,但这对我的逻辑结构来说是一个很大的改变,我放弃了这个想法,因为它似乎没有带来立竿见影的效果。我最初在
片段中有侦听器,因此它们可以直接访问数据模型

使用上述逻辑结构的一个缺点实际上是保留对片段的引用,并不断地来回传递信息,这不是很有效,并且可能会在以后导致内存泄漏

解决方案 当我考虑我的设置,并做了一些徒劳的跟踪和内存分析时,我意识到我忽略了一个重要因素

我的图像可能相对较小,但如果您的图像大于1000像素,则300kb并不重要。这意味着,当android渲染你的图像时,它实际上需要相当多的像素,并将其转换成
位图

我将我的图像放在
nodpi
文件夹中,以通过android“简化”图像选择,这一事实加剧了这个问题。安卓正在拍摄我的1000多张图片,并试图将其放入一个不超过200像素的按钮中。。。这需要大量的计算

所以我想我应该试着把我的图片缩小到一个更适合他们预期用途的尺寸,我很惊讶。我的300kb图像大小被减少到10kb!!!现在它们的大小更合适了,我启动了我的应用程序,没有任何崩溃

现在来看看我的其他虫子