listview выходит из памяти исключение, но без утечек памяти?

После Сота Google сказал, что растровые изображения управляются кучей (говорили оВот), поэтому, если растровое изображение больше не доступно, мы можем предположить, что GC позаботится об этом и освободит его.

Я хотел создать демонстрацию, которая показывает эффективность идей, показанных для лекции listView (отВот), поэтому я сделал небольшое приложение. Приложение позволяет пользователю нажимать кнопку, а затем просмотр списка полностью прокручивается до самого дна, в то время как в нем содержится 10000 элементов, содержимое которых представляет собой элементы android.R.drawable (имя и изображение).

По какой-то причине у меня не хватает памяти, хотя я не сохраняю ни одно из изображений, поэтому мой вопрос: как это может быть? Что мне не хватает?

Я тестировал приложение на Galaxy S III, и, тем не менее, продолжаю получать исключения из памяти, если использую собственную версию адаптера. Я не понимаю, почему это происходит, поскольку я ничего не храню.

Вот код:

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: я знаю, что для этого кода есть оптимизации (с использованием convertView и шаблона проектирования viewHolder), поскольку я упомянул видео со списком listView, созданное Google. Поверьте мне, я знаю, что лучше; в этом весь смысл кода.

Предполагается, что приведенный выше код показывает, что лучше использовать то, что вы (и видео) показывает. Но сначала мне нужно показать наивный путь; даже наивный способ все еще должен работать, так как я не сохраняю растровые изображения или представления, и так как Google сделал тот же тест (следовательно, они получили график сравнения производительности).

Ответы на вопрос(4)

Ваш ответ на вопрос