使用交错的gridview布局耗尽内存

时间:2014-09-04 16:52:54

标签: android performance android-layout android-gridlayout

我正在开发一个使用staggered gridview的应用程序我遇到了严重的性能问题,因为在加载了6,7个项目后,滚动非常滞后,我得到的时间减少了一半:OutOfMemoryError at“android.graphics.BitmapFactory .nativeDecodeStream(Native Method)“

这是我的适配器(我正在使用持有人模式):

package ngapps.socialbackground;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import ngapps.socialbackground.Util.ImageDownloaderTask;

/**
 * Created by Naor on 02/09/2014.
 */
public class ItemAdapter extends BaseAdapter {

    ArrayList<ImageItem> imageItemArrayList = new ArrayList<ImageItem>();
    Context context;

    static class ViewHolder {
        public TextView textView;
        public ImageView imageView;

        ViewHolder(View base) {
            textView = (TextView) base.findViewById(R.id.textView);
            imageView = (ImageView) base.findViewById(R.id.imageView);
        }
    }

    public ItemAdapter(Context context){
        this.context = context;
    }

    @Override
    public int getCount() {
        return imageItemArrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return imageItemArrayList.get(position);


    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void addItem(ImageItem imageItem){
        imageItemArrayList.add(imageItem);
        notifyDataSetChanged();
    }


    public void addItems(List<ImageItem> items) {
        imageItemArrayList.addAll(items);
        notifyDataSetChanged();
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder holder;
        if (convertView == null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.item_layout,null);
            holder = new ViewHolder(v);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        ImageItem curImageItem = imageItemArrayList.get(position);
        holder.textView.setText(curImageItem.getText());
        if (curImageItem.getPreviewBitmap() != null)
            holder.imageView.setImageBitmap(curImageItem.getPreviewBitmap());
        else
            new ImageDownloaderTask(holder.imageView, curImageItem).execute(curImageItem.getImageURL());

        return  v;

    }
}

这是ImageDownloaderTask:

package ngapps.socialbackground.Util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

import java.io.InputStream;

import ngapps.socialbackground.ImageItem;

/**
 * Created by Naor on 04/09/2014.
 */
public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;
    ImageItem imageItem;
    public ImageDownloaderTask(ImageView bmImage, ImageItem imageItem) {
        this.bmImage = bmImage;
        this.imageItem = imageItem;
    }

    protected Bitmap doInBackground(String... urls) {
        String url = urls[0];
        Bitmap mIcon = null;
        try {
            InputStream in = new java.net.URL(url).openStream();
            mIcon = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
        }
        return mIcon;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
        imageItem.setPreviewBitmap(result);
    }
}

图像宽约160像素, 我已经验证了持有者模式是有效的,我只创建了有限数量的视图,并且在图像下载完成后没有创建新的ImageDownloaderTask

并且在滚动完所有内容后仍然落后

是什么伤害了我的表现?

1 个答案:

答案 0 :(得分:0)

您的代码存在内存泄漏,我发布了解决方案并提示处理此问题here。可能OutOfMemoryException发生在代码的这一行:

InputStream in = new java.net.URL(url).openStream();
mIcon = BitmapFactory.decodeStream(in);