2010-01-15 27 views
5

我有一个包含图像图标(存储在drawables文件夹中)的70个文本项目的列表。 如果我第一次启动应用程序并缓慢滚动列表 - 不会发生异常。滚动图像列表时出现OutOfMemory异常

当应用程序被启动的第一时间,我滚动与“甩”动作列表中出现以下异常:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:439) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:688) 
at android.content.res.Resources.loadDrawable(Resources.java:1710) 
at android.content.res.Resources.getDrawable(Resources.java:585) 

之后,如果我杀死DDMS的应用程序,再次和滚动启动它与'一掷'动作,异常不会发生。因此,只有在第一次安装和启动应用程序时才会出现异常情况。

这里是我使用的列表中选择适配器:

public class AuthorAdapter extends ArrayAdapter<Author> { 

private ArrayList<Author> items; 
private Context context; 
private LayoutInflater inflater; 

public AuthorAdapter(Context context, int textViewResourceId, ArrayList<Author> items) { 
    super(context, textViewResourceId, items); 
    this.items = items; 
    this.context = context; 
    inflater = LayoutInflater.from(this.context); 
} 

static class ViewHolder { 
    ImageView authorFace; 
    TextView authorName; 
    TextView authorWho; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder holder; 

    if (convertView == null) { 
     convertView = inflater.inflate(R.layout.autor_data, null); 

     holder = new ViewHolder(); 
     holder.authorFace = (ImageView) convertView.findViewById(R.id.authorFaceImageView); 
     holder.authorName = (TextView) convertView.findViewById(R.id.authorNameTextView); 
     holder.authorWho = (TextView) convertView.findViewById(R.id.authorWhoTextView); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    Author author = items.get(position); 
    if (author != null) { 
     if (holder.authorFace != null) { 
      String faceFileName = author.getFace(); 
      String facePlaceName = context.getPackageName() + ":drawable/" + faceFileName.subSequence(0, faceFileName.lastIndexOf(".")); 
      int faceFileId = context.getResources().getIdentifier(facePlaceName, null, null); 
      holder.authorFace.setImageResource(faceFileId); 
     } 
     if (holder.authorName != null) { 
      holder.authorName.setText(author.getName()); 
     } 
     if (holder.authorWho != null) { 
      holder.authorWho.setText(author.getWho()); 
     } 
    } 
    return convertView; 
} 

}

有没有办法避免的异常? 我应该捕捉异常并以某种方式逃离内存吗?

任何建议如何做到这一点?

谢谢。

+0

您的图片有多大 – 2010-01-15 15:01:46

+0

列表项图片大小约为3KB。我使用两个活动(主要和列表)。活动背景图像每个大约60KB。还有我用于UI控件的图像,总共大约100 KB。它可能是一个模拟器问题? 不幸的是,我现在无法在设备上试用我的应用程序。 – Zzokk 2010-01-18 07:09:50

回答

3

你不能赶上java.lang.OutOfMemoryError。他们非常致命。

现在,你说这个问题只发生在你第一次运行你的应用程序。这使我认为问题不是与视图代码。如果用户使用大量资源浏览资源,它可能会占用大量内存,但正如您所说,通常您的应用程序可以正常工作。

那么 - 您在第一次运行应用程序时做了什么初始化?首次运行一次的任务是否有可能泄漏内存,意味着没有足够的剩余空间来使用您的视图?

+0

实际上,当我第一次启动应用程序时,我不会初始化任何图像。我所有的图像都存储在drawables文件夹中。我只为该列表设置适配器。在适配器的getView()方法中,我为每个列表项设置图像(请参阅上面的代码): holder.authorFace.setImageResource(faceFileId); 据我所知getView()方法每次在手机屏幕上显示一个列表项。可能当我快速滚动列表时,缓存没有时间回收。 当我慢慢地滚动列表时,没有观察到异常。 – Zzokk 2010-01-15 10:23:05

+2

我想知道是否有一些其他的初始化行为正在泄漏内存,所以当你快速滚动视图时,堆上没有空间存储大量图像。这可以解释为什么只有在您第一次运行应用程序时才会出现问题。 – 2010-01-15 10:44:47

+1

同意戴夫,我会开始看你在做什么,你第一次启动应用程序与正常启动。在应用程序的第一次初始化期间,您会抓住一些重要的东西。 – 2010-01-15 15:10:03

相关问题