2014-12-12 3 views
0

Java와 Android Dev를 사용하면 어쨌든 5 분 동안 안드로이드 애플리케이션을 사용할 때 오류가 발생하고 로그에 OOM 오류가 표시됩니다. ,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; 
} 
} 

임 내 ListView에 대한 목록 어댑터를 사용하여 : 내 응용 프로그램이있는 ListView에 항목의 목록을 보여줍니다, 모든 항목이 모두 데이터베이스에서 요청되는 비트 맵과 정보가 포함되어 있습니다, 여기 내 활동 클래스의 코드입니다 여기 클래스 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; 

} 

}

내가 그 activy에 많은 시간을 입력 할 때까지 crashe 나던, 처음에 THT이보기 나던 충돌을 고려하시기 바랍니다, 감사합니다.

+0

모든 비트 맵 이미지를 목록에로드하여 코드에 표시되면 OOM 오류가 발생합니다. 파일 경로 또는 이미지와 같은 이미지에 대한 참조를 유지하고 필요할 때 목록에로드해야합니다. – tyczj

+0

각 연락처에 대해 얼마나 많은 연락처가 있고 얼마나 큰 이미지를로드하고 있습니까? – Kai

답변

0

작업이 완료 될 때 비트 맵을 처리하지 않으므로 메모리 누수가 발생했습니다. 더 이상 필요하지 않을 때 사용하는 메모리를 비우려면 비트 맵에서 recycle 메서드를 호출해야합니다. 또는 더 많이 최적화하려면 비트 맵 here을 캐싱하여 동일한 이미지를 사용하여 해당 활동을 많이 수행하는 경우 해당 이미지를 메모리에 유지하십시오.

+0

코드에서 OOM을 얻는 위치를 결정해야합니다. 이미지 스트림을 읽을 때 어댑터에 있습니까? ImgArry.add()에 있습니까? – Martin

+0

활동에서 비트 맵을 참조하는 경우 메모리가 자동으로 회수됩니다. recycle()은 예측할 수있는 메모리 재생 목적을 제공하기 위해 사전 허니 콤 장치에만 유용합니다. – Kai