Отображение более 100000 элементов в ListView из базы данных SQLite

Я пытаюсь отобразить все элементы из предварительно заполненной базы данных (с более чем 100000 строк) в ListView с помощью курсоров. Это работает, но для запуска приложения и отображения ListView требуется несколько минут. Есть ли более быстрый способ? Я кое-что читал о таблицах FTS3, поможет ли это?

Я использую ArrayList<HashMap<String, String>> с SimpleAdapter и пользовательским 2-строчным макетом. Код:

Cursor cursor = sDictionary.query("FTSgesla", new String[] {PodatkovnaBaza.KEY_WORD, PodatkovnaBaza.KEY_DEFINITION}, null, null, null, null, PodatkovnaBaza.KEY_WORD);

    if (cursor == null) 
    {

            // There are no results
            mTextView.setText("Empty");
    } 
    else 
    {

        HashMap<String, String> item;

        if(cursor.moveToFirst())
        {
            do
            {
                item = new HashMap<String, String>();
                item.put("line1", cursor.getString(0));
                item.put("line2", cursor.getString(1));
                list.add(item);
            }
            while(cursor.moveToNext());
        }

            sa = new SimpleAdapter(GlavniActivity.this, list,
                    R.layout.result,
                    new String[] { "line1","line2" },
                    new int[] {R.id.word, R.id.definition});

            mListView.setAdapter(sa);
            // Define the on-click listener for the list items
            mListView.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                   //do something
                }
            });
        }

person domen    schedule 28.01.2013    source источник


Ответы (4)


Нет более быстрого способа загрузить 100000 элементов, и вашему пользователю также не нужно будет видеть все сразу, следовательно, загружайте их один за другим с потоком.

    private class SQLTask extends AsyncTask<Integer, String[], Integer> {

    @Override
    protected Integer doInBackground(Integer... params) {
        db.open();
        Cursor c = db.getAllDataCursor();
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
            String[] temp = new String[c.getColumnCount()];
            for (int i = 0; i < temp.length; i++) {
                temp[i] = c.getString(i);
            }
            publishProgress(thisTask, temp);
        }
        c.close();
        db.close();
    }

    @Override
    protected void onProgressUpdate(String[]... values) {
        super.onProgressUpdate(values);
        // LOAD ONE ROW
    }
}
person wtsang02    schedule 28.01.2013
comment
Есть ли команда SQLite, которая вернет курсор с 1000 случайных значений из базы данных? - person domen; 29.01.2013
comment
sql не имеет случайного, но вы можете использовать подготовленный статус и привязку, чтобы сделать это. - person wtsang02; 29.01.2013
comment
Я пытаюсь использовать ваш код, но где и как мне загрузить строки в ListView? - person domen; 29.01.2013
comment
Сначала вы создаете свой список и адаптер, а затем добавляете каждую строку в OnProgressUpdate(); этот пост может помочь. - person wtsang02; 29.01.2013

Это должно быть в разделах с какой-то фильтрацией, загрузка такого количества элементов кажется чрезмерной.

person draksia    schedule 28.01.2013

Я не очень уверен, но боюсь, ваша проблема в том, что вы загружаете 100 000 просмотров одновременно. Лично я бы использовал ArrayAdapter или базовый адаптер, переопределил метод getView(..) и, конечно же, использовал шаблон ViewHolder.

Вот пример очень плавного и быстрого использования BaseAdapter: https://github.com/Jachu5/RSS_Feeder_Android/tree/master/RssFeeder_sherlock/src/com/example/adapter

Надеюсь, поможет!

person Jachu    schedule 28.01.2013

Почему вы когда-либо загружали 100 000 элементов в список? Список — это экранный элемент, с которым будет взаимодействовать пользователь. Никто никогда не будет прокручивать 100 тысяч элементов. Даже 1% из этого никто не прокрутит. Ответ здесь заключается в том, чтобы не загружать их все.

person Gabe Sechan    schedule 28.01.2013