安卓位图OOM(内存不足错误)



我是使用 Java 和 Android Dev 的新手,无论如何,当我使用它 5 分钟时,我的 android 应用程序崩溃了,它在日志上显示 OOM 错误。我的 App 在 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;
}
}

我为我的列表视图使用列表适配器,这里是类列表适配器。

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;
}

}

请考虑一下这个视图不会在第一次崩溃,直到我多次进入该活动它才崩溃,谢谢。

您有内存泄漏,因为您在活动完成时不会释放位图。您需要在位图上调用回收方法,以便在不再需要它们时释放它们使用的内存。或者,要进一步优化,请查看在此处缓存位图,以便在使用相同的图像经常点击该活动时将这些图像保留在内存中。

最新更新