从sdcard加载图像(作为位图)到gridview时获取OutOfMemoryError

时间:2014-04-16 15:03:10

标签: java android bitmap android-asynctask

我正在开发一个包含大量位图及其处理的Android应用程序。我经常发生内存崩溃。 我搜索了很多正确和标准的方法来加载位图和我在这里得到的最好的方法 Loading Large Bitmaps Efficiently

现在这已经减少了崩溃的频率,但是仍然有一些崩溃到某些特定区域,例如,当显示存储在SDCARD中的图像到gridview时,即使我使用异步任务加载,我每次都会出现内存崩溃图像。

我正在添加代码以及这些问题,请查看并告诉我代码有什么问题:

LoadImage AsyncTask的PostExecute方法

protected void onPostExecute(final Bundle result) {
        super.onPostExecute(result);
        ImageView view = views.get(result.getInt("pos"));
        view.setImageBitmap(BitmapFactory.decodeFile(result.getString("filePath")));
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(context, Monsterize.class);
                i.putExtra("flagtwo", 3);
                i.putExtra("backbgpath", filepath);
                i.putExtra("backbgname", fileName);
                i.putExtra("backbgpos", result.getInt("pos"));
                i.putExtra("calledFrom", context.getClass().getSimpleName());
                context.startActivity(i);
            }
        });
    }

Async taks正在从网格视图适配器的getview方法调用

public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    if (convertView == null)
        vi = inflater.inflate(R.layout.gridview_item, null);
    ImageView image = null;
    if (vi != null) {
        image = (ImageView) vi.findViewById(R.id.image);
    }
    Bundle b = new Bundle ();
    b.putString("filePath", filepath[position]);
    b.putInt("pos", position);
    new LoadImage().execute(b);
    views.put(position, image);
    return vi;
}

views是一个hashmap,包含postion作为键,Imageview作为值。在异步任务中,图像根据位置在imageview中设置。

3 个答案:

答案 0 :(得分:0)

您可以使用通用图像加载器来完成这项工作,它将处理与内存相关的问题。 通过以下链接。

Android Universal Image loader

答案 1 :(得分:0)

views.put(position, image);
  

views是一个散列映射,其中postion为键,Imageview为value

这就是问题所在。虽然网格视图正在管理其视图,重用它们,以便只有可见的视图占用内存,但您将所有图像视图存储在内存中。不清楚你为什么这样做 - views从未在你的来源中使用 - 但它始终引用所有图像。

答案 2 :(得分:-1)

首先,您在onPostExecute中解码位图。在UI thread上执行此方法时,它会使您的应用变慢。

位图应使用doInBackground方法解码,并设置为ImageView中的onPostExecute

其次,在适配器中,当用户在GridView中滚动时,会创建和销毁视图。

您可能希望使用HashMap<String, Bitmap>来存储位图,并避免两次解码相同的位图。使用文件路径作为键,使用位图作为值。