2014-12-12 1 views
0

Im new при использовании Java и Android Dev в любом случае сбой приложения для Android, когда я использую его в течение 5 минут, и он показывает ошибку OOM в журналах. моего приложение показывает список Пункта На ListView, каждый элемент содержит растровое изображение и информация Оба Запрошенные Из базы данных, вот код моего класса активности:Android-растровое изображение OOM (из-за ошибки памяти)

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

Im используя список Адаптер для моей ListView, и вот список ClassAdapter.

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; 

} 

}

Пожалуйста, обратите внимание THT этой аварию вида оленью кожи в первый раз, оно не аварийное завершение, пока я не вводить много раз к этому ACTIVY, спасибо.

+0

Если вы загружаете все ваши растровые изображения в список, который он отображается по вашему коду, тогда да, вы получите ошибки OOM. вы должны хранить ссылку на изображение, например путь к файлу или что-то еще, и загружать их только в списке, когда вам это нужно. – tyczj

+0

Сколько контактов у вас есть и сколько именно изображений, которые вы загружаете для каждого контакта? – Kai

ответ

0

У вас есть утечка памяти, так как вы не удаляете свои растровые изображения, когда заканчивается ваша деятельность. Вам нужно вызвать метод перезаписи на ваших растровых изображениях, чтобы освободить память, используемую ими, когда вы больше не нуждаетесь в них. Или, чтобы еще больше оптимизировать, загляните в кеширование ваших растровых изображений here, чтобы сохранить эти изображения в памяти, если вы сильно нажмете на эту деятельность с теми же изображениями.

+0

, вы должны, вероятно, определить ГДЕ в своем коде, который вы получаете OOM. Является ли ваш адаптер при чтении потока изображений? Это в ImgArry.add()? – Martin

+0

Это неверно, если битмап ссылается только на Activity, его память будет автоматически восстановлена. recycle() полезен только для устройств с предварительной сотой, чтобы обеспечить предсказуемую цель рекультивации памяти. – Kai

 Смежные вопросы

  • Нет связанных вопросов^_^