所以我在Google Play商店发布了我的第一个Android应用程序(COD Emeblem Tutorials)。我已经获得了很多下载,但是当你在动态加载的列表中滚动得足够远时,我注意到它崩溃了。
我加载教程的方法是调用对我网站的API调用。信息返回后,我会为每个教程显示一个ImageView&有一个异步任务去下载图像,如下所示。每当它到达第500个教程时,应用程序崩溃并出现以下错误。我认为它说堆已经没有内存了。知道如何防止这种情况发生吗?这是因为屏幕上有太多的ImageView?
public class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {
ImageView bmImage;
String id;
ProgressBar progressbar;
public DownloadImageTask(ImageView bmImage, ProgressBar progressbar, String id) {
this.bmImage = bmImage;
this.id = id;
this.progressbar = progressbar;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
//Log.v("COD","doInBackground");
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
progressbar.setVisibility(View.GONE);
Image img = new Image(id, result);
Brain.addImage(img);
bmImage.setImageBitmap(result);
}
}
> 11-10 19:11:59.952: E/dalvikvm-heap(1341): Out of memory on a 135440-byte allocation.
11-10 19:11:59.952: I/dalvikvm(1341): "AsyncTask #1" prio=5 tid=13 RUNNABLE
11-10 19:11:59.952: I/dalvikvm(1341): | group="main" sCount=0 dsCount=0 obj=0x4262ab40 self=0x5cf7ee20
11-10 19:11:59.952: I/dalvikvm(1341): | sysTid=1405 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1623637296
11-10 19:11:59.952: I/dalvikvm(1341): | state=R schedstat=( 0 0 0 ) utm=647 stm=148 core=0
11-10 19:11:59.952: I/dalvikvm(1341): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-10 19:11:59.952: I/dalvikvm(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
11-10 19:11:59.952: I/dalvikvm(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:696)
11-10 19:11:59.952: I/dalvikvm(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:30)
11-10 19:11:59.962: I/dalvikvm(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:1)
11-10 19:11:59.962: I/dalvikvm(1341): at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-10 19:11:59.962: I/dalvikvm(1341): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-10 19:11:59.962: I/dalvikvm(1341): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-10 19:11:59.962: I/dalvikvm(1341): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-10 19:11:59.962: I/dalvikvm(1341): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-10 19:11:59.962: I/dalvikvm(1341): at java.lang.Thread.run(Thread.java:841)
11-10 19:11:59.962: D/skia(1341): --- decoder->decode returned false
11-10 19:11:59.962: W/dalvikvm(1341): threadid=13: thread exiting with uncaught exception (group=0x41830898)
11-10 19:11:59.972: E/AndroidRuntime(1341): FATAL EXCEPTION: AsyncTask #1
11-10 19:11:59.972: E/AndroidRuntime(1341): java.lang.RuntimeException: An error occured while executing doInBackground()
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.lang.Thread.run(Thread.java:841)
11-10 19:11:59.972: E/AndroidRuntime(1341): Caused by: java.lang.OutOfMemoryError
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:696)
11-10 19:11:59.972: E/AndroidRuntime(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:30)
11-10 19:11:59.972: E/AndroidRuntime(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:1)
11-10 19:11:59.972: E/AndroidRuntime(1341): at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-10 19:11:59.972: E/AndroidRuntime(1341): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-10 19:11:59.972: E/AndroidRuntime(1341): ... 4 more
11-10 19:12:00.103: D/AbsListView(1341): unregisterIRListener() is called
11-10 19:12:00.373: D/dalvikvm(1341): GC_FOR_ALLOC freed 168K, 13% free 85864K/98208K, paused 127ms, total 132ms
11-10 19:12:00.373: I/dalvikvm-heap(1341): Forcing collection of SoftReferences for 131776-byte allocation
11-10 19:12:00.513: D/dalvikvm(1341): GC_BEFORE_OOM freed <1K, 13% free 85863K/98208K, paused 134ms, total 142ms
11-10 19:12:00.513: E/dalvikvm-heap(1341): Out of memory on a 131776-byte allocation.
11-10 19:12:00.523: I/dalvikvm(1341): "AsyncTask #3" prio=5 tid=20 RUNNABLE
11-10 19:12:00.523: I/dalvikvm(1341): | group="main" sCount=0 dsCount=0 obj=0x42f01eb8 self=0x61ad5728
11-10 19:12:00.523: I/dalvikvm(1341): | sysTid=1532 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1637026936
11-10 19:12:00.523: I/dalvikvm(1341): | state=R schedstat=( 0 0 0 ) utm=1051 stm=119 core=0
11-10 19:12:00.523: I/dalvikvm(1341): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-10 19:12:00.523: I/dalvikvm(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
11-10 19:12:00.523: I/dalvikvm(1341): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:696)
11-10 19:12:00.523: I/dalvikvm(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:30)
11-10 19:12:00.533: I/dalvikvm(1341): at com.codplayercards.codplayercards.DownloadImageTask.doInBackground(DownloadImageTask.java:1)
11-10 19:12:00.533: I/dalvikvm(1341): at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-10 19:12:00.533: I/dalvikvm(1341): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-10 19:12:00.533: I/dalvikvm(1341): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-10 19:12:00.533: I/dalvikvm(1341): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-10 19:12:00.533: I/dalvikvm(1341): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-10 19:12:00.533: I/dalvikvm(1341): at java.lang.Thread.run(Thread.java:841)
11-10 19:12:00.553: D/skia(1341): --- decoder->decode returned false
11-10 19:12:00.583: W/dalvikvm(1341): threadid=20: thread exiting with uncaught exception (group=0x41830898)
11-10 19:12:00.593: I/Process(1341): Sending signal. PID: 1341 SIG: 9
答案 0 :(得分:1)
我强烈建议您使用Picasso
它是一个出色的库,可以满足您的所有需求,而且它具有出色的缓存,易于使用,您可以在代码中的任何位置使用它,从简单的imageview到列表(它可以循环使用)本身!)。 哦,而且,他们的文档非常出色!
答案 1 :(得分:0)
您是否将图片加载到列表视图? 如果要将图像加载到列表视图,请考虑仅加载所需的图像。 如果您的图像分辨率太大,请考虑将尺寸缩小到较小的分辨率。 最后,请确保回收位图以查找将移出可见范围的图像。
如果您已完成上述所有操作,则应该可以防止您在Android加载图片时出现内存不足错误。
如果你想轻松,自动处理图像加载,你应该考虑使用volley networkimageview,如Eugen Pechanec建议的那样。 Volley还具有图像缓存功能,可以在第二次尝试时加快图像加载速度。
答案 2 :(得分:0)
当您为处理多个图像集或大位图或某些动画内容的应用程序开发时,内存不足错误是非常常见的错误。在这种情况下,我们必须在处理图像或对象分配和释放时非常小心和高效。当分配超过堆限制或您的进程需要超过堆限制的内存量时,会出现OOM错误。
在Android中,每个应用程序都在Linux进程中运行。每个Linux进程都在其中运行虚拟机(Dalvik虚拟机)。进程可以要求的内存有一个限制,它对于不同的设备是不同的,并且对于手机和平板电脑也是不同的。当某个进程需要比其限制更高的内存时,会导致错误,即内存不足错误。
可能的原因:
我们遇到内存不足错误的原因有很多。其中一些是:
您正在进行一些持续需要大量内存的操作,并且在某些时候它超出了进程的最大堆内存限制。
您正在泄漏一些内存,即您没有使之前分配的对象符合垃圾收集(GC)的条件。这称为内存泄漏。
您正在处理大型位图并在运行时加载所有这些位图。你必须非常小心地处理大位图,只需加载你需要的大小而不是整个位图,然后进行缩放。
内存不足的最大原因是内存泄漏。
在您的情况下,您正在使用位图并将其加载到内存中。 因此,最好修复这些位图的最大内存,这样当达到内存限制时,它将删除未使用的位图。 UniversalImageloader是一个很好的liabrary用于你的工作,他们提供了非常有效的缓存实现,你不需要自己加载位图,Liabrary将为你管理。 please refer the link