listview hat keine Speicherausnahme mehr, aber keine Speicherlecks?

Nach Honeycomb sagte Google, dass Bitmaps vom Haufen verwaltet werden (worüber gesprochen wird)Hier), wenn also eine Bitmap nicht mehr verfügbar ist, können wir davon ausgehen, dass GC sich darum kümmert und sie freigibt.

Ich wollte eine Demo erstellen, die die Effizienz der für die ListView - Vorlesung gezeigten Ideen zeigtHier), also habe ich eine kleine App gemacht. Die App lässt den Benutzer eine Taste drücken, und die Listenansicht scrollt dann ganz nach unten, während sie 10000 Elemente enthält, deren Inhalt die android.R.drawable-Elemente (Name und Bild) sind.

Aus irgendeinem Grund geht mir der Speicher aus, obwohl ich keines der Bilder speichere. Deshalb lautet meine Frage: Wie könnte es sein? Was fehlt mir?

Ich habe die App auf einem Galaxy S III getestet und bekomme dennoch immer wieder Ausnahmen, wenn ich die native Version des Adapters verwende. Ich verstehe nicht, warum es auftritt, da ich nichts speichere.

Hier ist der Code:

public class MainActivity extends Activity
  {
  private static final int LISTVIEW_ITEMS =10000;
  long                     _startTime;
  boolean                  _isMeasuring   =false;

  @Override
  public void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ListView listView=(ListView)findViewById(R.id.listView);
    final Field[] fields=android.R.drawable.class.getFields();
    final LayoutInflater inflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // listen to scroll events , so that we publish the time only when scrolled to the bottom:
    listView.setOnScrollListener(new OnScrollListener()
      {
        @Override
        public void onScrollStateChanged(final AbsListView view,final int scrollState)
          {
          if(!_isMeasuring||view.getLastVisiblePosition()!=view.getCount()-1||scrollState!=OnScrollListener.SCROLL_STATE_IDLE)
            return;
          final long stopTime=System.currentTimeMillis();
          final long scrollingTime=stopTime-_startTime;
          Toast.makeText(MainActivity.this,"time taken to scroll to bottom:"+scrollingTime,Toast.LENGTH_SHORT).show();
          _isMeasuring=false;
          }

        @Override
        public void onScroll(final AbsListView view,final int firstVisibleItem,final int visibleItemCount,final int totalItemCount)
          {}
      });
    // button click handling (start measuring) :
    findViewById(R.id.button).setOnClickListener(new OnClickListener()
      {
        @Override
        public void onClick(final View v)
          {
          if(_isMeasuring)
            return;
          final int itemsCount=listView.getAdapter().getCount();
          listView.smoothScrollToPositionFromTop(itemsCount-1,0,1000);
          _startTime=System.currentTimeMillis();
          _isMeasuring=true;
          }
      });
    // creating the adapter of the listView
    listView.setAdapter(new BaseAdapter()
      {
        @Override
        public View getView(final int position,final View convertView,final ViewGroup parent)
          {
          final Field field=fields[position%fields.length];
          // final View inflatedView=convertView!=null ? convertView : inflater.inflate(R.layout.list_item,null);
          final View inflatedView=inflater.inflate(R.layout.list_item,null);
          final ImageView imageView=(ImageView)inflatedView.findViewById(R.id.imageView);
          final TextView textView=(TextView)inflatedView.findViewById(R.id.textView);
          textView.setText(field.getName());
          try
            {
            final int imageResId=field.getInt(null);
            imageView.setImageResource(imageResId);
            }
          catch(final Exception e)
            {}
          return inflatedView;
          }

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

        @Override
        public Object getItem(final int position)
          {
          return null;
          }

        @Override
        public int getCount()
          {
          return LISTVIEW_ITEMS;
          }
      });
    }
  }

@all: Ich weiß, dass es Optimierungen für diesen Code gibt (mithilfe von convertView und viewHolder), da ich das Video der von Google erstellten listView erwähnt habe. Glauben Sie mir, ich weiß, was besser ist. Das ist der springende Punkt des Codes.

Der obige Code soll zeigen, dass es besser ist, das zu verwenden, was Sie (und das Video) zeigen. Aber zuerst muss ich den naiven Weg zeigen; Selbst die naive Art sollte noch funktionieren, da ich weder die Bitmaps noch die Ansichten speichere und Google den gleichen Test durchgeführt hat (daher haben sie eine Grafik des Leistungsvergleichs erhalten).

Antworten auf die Frage(4)

Ihre Antwort auf die Frage