我正在尝试防止我的android应用程序中出现OutOfMemoryError。我读过很多帖子,但我还不能解决它。
该应用程序有背景活动,所以我认为这是主要问题。OutOfMemoryError仅在某些设备中发生(可能是由于VM堆),我需要确保此错误不会在任何设备中产生崩溃。
我最近读了关于MAT(内存分析插件),我在应用程序运行时执行了它,在这里你可以看到结果:
支配树
汇报
在这项活动中,我对每个方向(家、家和土地)都有一个背景。两个大小都相同(190kb,jpg)。当我创建HPROF文件时,活动是横向的,我以前没有运行过纵向的。为了达到目的,我可以从这个结果中得出什么结论?
如果有必要我可以补充更多信息
编辑
为了避免OutOfMemoryError,我尝试使用此页面的方法,但我无法获得它。这是我的密码:
decodeFromResource类
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
public class decodeFromResource {
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static Drawable getDecodedDrawableFromResource(Resources res, int resId,
int reqWidth, int reqHeight){
return new BitmapDrawable(res, decodeSampledBitmapFromResource(res, resId, reqWidth, reqHeight));
}
}
来自主活动的onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
resources = getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
layoutHome = (LinearLayout) findViewById(R.id.home_layout);
if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
layoutHome.setBackgroundDrawable(decodeFromResource
.getDecodedDrawableFromResource(resources, R.drawable.home,
metrics.widthPixels, metrics.heightPixels));
} else {
layoutHome.setBackgroundDrawable(decodeFromResource
.getDecodedDrawableFromResource(resources,
R.drawable.home_land, metrics.heightPixels,
metrics.widthPixels));
}
我只在后台实现了“高效加载大位图”的方法,因为除此之外,我只有五个非常小的按钮。我是否也需要为他们实现该方法?你能看到任何错误吗?
options.inPurgeable = true;
options.inInputShareable = true;
这些标志允许在内存压力下丢弃与位图
对象关联的实际位,并在您仍在使用位图
时透明地重新解码。
尝试使用Android: largeHeap="true"标签在你的Androidanifest.xml这应该确保Android将处理更大的位图。
编辑
我必须指出,这不是问题的最终解决方案,它不会阻止OutOfMemory异常,但它们不太可能出现。也许吉拉德·海莫夫提出了解决这个问题的正确方法
您可能正在按原样加载jpg文件,这很容易导致内存不足,即使在功能强大的设备上也是如此。
请记住,加载到内存中的图像没有压缩,在大多数设备上,单个像素由4个内存字节表示。例如,一个7 MPixel的图像需要28兆字节的内存块,这可能会使你的应用程序真正接近OutOfMemory崩溃。
解决方案很简单:始终根据应用程序的需要加载缩小的图像。
要做到这一点,请从读取图像大小开始:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
上面的代码不会加载实际的图像文件。它只会询问它的尺寸。
一旦你有了定义,你就可以计算用于加载缩放图像的“样本大小”。N的样本大小将导致加载1/(N*N)的原始图像像素,例如对于4的样本大小,仅加载1/16的图像像素。
最后加载缩小的图像:
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = mySampleSize; //<-----------------------
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeResource(res, resId, options);
即使在执行按比例缩小的加载时,也最好使用try{...}捕获(OutOfstore)子句来保护代码,并允许优雅地处理加载失败。
详情如下:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
问题内容: 我有一个自定义的JDialog,当我的SwingWorker线程启动时会弹出。该对话框只有一个JProgressbar和一个Button(取消按钮)。我试图弄清楚如何取消我的SwingWorker,但是没有运气。我想我走对了。我编写了一个cancel方法,现在我只需要弄清楚按下按钮时如何调用它。代码如下… 问题答案: 您的取消按钮应调用该方法 在您的工作人员中,必须确保检查取消标志 请
指定文档设置选项 可以随时更改文档的默认设置选项,如度量单位、透明度网格显示、背景颜色和文字设置(例如,语言、引号样式、上标和下标大小、出血以及可导出性)。单击 “编辑画板 ”按钮可关闭此对话框并激活画板工具。 1选择 “文件 ”>“文档设置 ”或单击 “控制 ”面板中的 “文档设置 ”按钮。(当未选择任何内容时,此按钮可用。) 2根据需要指定选项。 3如果要编辑画板,请单击 “编辑画板 ”进入画
问题内容: 我对Go如何处理非阻塞IO感到困惑。API在我看来基本上是同步的,并且在Go上观看演示时,听到诸如“和调用块”之类的注释并不罕见。 从文件或网络读取时,Go是否使用阻塞IO?还是当在Go Routine中使用某种魔术来重写代码? 来自C#背景,这感觉非常不直观,在C#中,当使用异步API时我们使用了关键字。这清楚地表明,API可以产生当前线程,并在以后的延续中继续。 因此,TLDR;当
主要内容:查看视图的字段信息,查看视图的详细信息,拓展阅读创建好视图后,可以通过查看视图的语句来查看视图的字段信息以及详细信息。本节主要讲解如何使用 SQL 语句来查看视图的字段信息以及详细信息。 查看视图的字段信息 查看视图的字段信息与查看数据表的字段信息一样,都是使用 DESCRIBE 关键字来查看的。具体语法如下: DESCRIBE 视图名; 或简写成: DESC 视图名; 示例 1 下面创建学生信息表 studentinfo 的一个视图,用于查询
我有下面的屏幕(图像),当按下按钮时,它会显示一个侧菜单。菜单会出现,另外我还有一个uitableview来显示其他内容 我的问题是,当侧菜单出现时,uitableview的大小会调整。 我如何保持我的uitableview完整?我一直在尝试下一个,但我没有得到任何东西:
在我的Espresso测试执行和AlertDialog会被提示并等待用户响应。Espresso测试只有在我按下“Accept”按钮但我想测试代替用户执行此事件时才会继续。 我注意到我的线程选项卡上有以下状态