Android位图OOM(内存不足错误)

时间:2014-12-12 21:28:08

标签: android listview bitmap crash listadapter

我最初使用Java和Android Dev无论如何我的android应用程序在我使用它5分钟时崩溃了,它显示了日志上的OOM错误。 我的应用程序显示ListView上的项目列表,每个项目包含一个位图和信息都来自数据库,这是我的活动代码类:

public class QuotesActivity extends Activity {
private ArrayList<Quote> imageArry = new ArrayList<Quote>();
private QuotesListAdapter adapter;
private String Activitytype;
private DataBaseHandler db;
private AdView adView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quotes);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setDisplayShowHomeEnabled(true);
    db = new DataBaseHandler(this);
    Activitytype = getIntent().getExtras().getString("mode");

    }

    if (Activitytype.equals("allQuotes")) {

        List<Quote> contacts = db.getAllQuotes();
        for (Quote cn : contacts) {

            imageArry.add(cn);

        }
        ;

        }

    adapter = new QuotesListAdapter(this, R.layout.quote_items, imageArry);
    ListView dataList = (ListView) findViewById(R.id.quotesList);
    dataList.setAdapter(adapter);

    dataList.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View viewClicked,
                int position, long idInDB) {

            Intent i = new Intent(getApplicationContext(),
                    QuoteActivity.class);
            Quote srr = imageArry.get(position);
            i.putExtra("id", srr.getID());
            i.putExtra("mode", "");

            startActivity(i);

        }

    });

    adView = new AdView(this);
    adView.setAdUnitId(AD_UNIT_ID);
    adView.setAdSize(AdSize.SMART_BANNER);
    LinearLayout layout = (LinearLayout) findViewById(R.id.layAdsQuotes);
    layout.addView(adView);
    AdRequest adRequest = new AdRequest.Builder().build();
    adView.loadAd(adRequest);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.quotes, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        this.finish();
        break;
    }
    return true;
}
}

我正在为ListView使用A List Adapter,这是Class ListAdapter。

public class QuotesListAdapter extends ArrayAdapter<Quote> {
Context context;
int layoutResourceId;
private int lastPosition = -1;

ArrayList<Quote> data = new ArrayList<Quote>();

public QuotesListAdapter(Context context, int layoutResourceId,
        ArrayList<Quote> data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;

}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View row = convertView;

    ImageHolder holder = null;
    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        holder = new ImageHolder();
        holder.txtTitle = (TextView) row.findViewById(R.id.txtTitle);
        holder.txtTitle.setTextColor(Color.rgb(26, 188, 156));
        holder.imgIcon = (ImageView) row.findViewById(R.id.imgIcon);
        holder.txtQuote = (TextView) row.findViewById(R.id.txtQuote);
        holder.txtCategory = (TextView) row.findViewById(R.id.txtCategory);

        Typeface font = Typeface.createFromAsset(context.getAssets(),
                "fonts/Roboto-Light.ttf");
        holder.txtTitle.setTypeface(font);
        holder.txtTitle.setTextSize(16);
        holder.txtQuote.setTypeface(font);
        holder.txtQuote.setTextSize(16);
        holder.txtCategory.setTypeface(font);
        row.setTag(holder);
    } else {
        holder = (ImageHolder) row.getTag();
    }
    Animation animation = AnimationUtils.loadAnimation(getContext(),
            (position > lastPosition) ? R.anim.up_from_bottom
                    : R.anim.down_from_top);
    row.startAnimation(animation);
    lastPosition = position;

    Quote picture = data.get(position);
    holder.txtTitle.setText(picture.getName());
    holder.txtQuote.setText(picture.getQuote());

    holder.txtCategory.setText("    " + picture.getCategory() + "    ");

    byte[] outImage = picture.getImage();
    ByteArrayInputStream imageStream = new ByteArrayInputStream(outImage);
    Bitmap theImage = BitmapFactory.decodeStream(imageStream);
    holder.imgIcon.setImageBitmap(theImage);

    return row;
}

static class ImageHolder {
    ImageView imgIcon;
    TextView txtTitle;
    TextView txtQuote;
    TextView txtCategory;

}

}

请考虑这个视图在第一次没有崩溃,它不会崩溃,直到我进入该活动的很多时间,谢谢。

1 个答案:

答案 0 :(得分:0)

由于在活动结束时您没有处理位图,因此存在内存泄漏。您需要在位图上调用recycle方法,以便在不再需要它们时释放它们使用的内存。或者为了进一步优化,请查看缓存位图here,以便在使用相同图像进行大量活动时将这些图像保留在内存中。