Android: Грешка на курсора на SQLite над 1 MB размер на базата данни

Разработвам приложение, използвайки базата данни SQLite. Имам следния код за получаване на всички стойности от базата данни.

ArrayList<String> values=new ArrayList<String>(); 
String[] ColumnNames;
String selectQuery="SELECT * FROM "+tableName;
Cursor cursor=sDataBase.rawQuery(selectQuery, null);
if(cursor!=null && cursor.getColumnCount()>0 && cursor.getCount()>0){
    ColumnNames=cursor.getColumnNames();
    if (cursor.moveToFirst()){
        do{
            String value="";
            for(int i=0;i<cursor.getColumnCount();i++){
                if(value!="")
                    value=value +", \\\""+ColumnNames[i]+"\\\":\\\"" + cursor.getString(i)+"\\\"";
                else
                    value= "\\\""+ ColumnNames[i] +"\\\":\\\"" + cursor.getString(i) +"\\\"";
            }
            value="{" + value + "}";
            values.add(value);
        }while(cursor.moveToNext());
    }
    cursor.close();
}

Ако размерът на базата данни е повече от 1 MB, приложението се срива. Как мога да получа стойностите на базата данни повече от 1 MB.?

РЕДАКТИРАНЕ1:

Стойности на Logcat:

10-10 14:46:24.863: E/dalvikvm-heap(3248): Out of memory on a 6612888-byte allocation.

РЕДАКТИРАНЕ 2:

Код с помощта на stringbuffer

   if(cursor!=null && cursor.getColumnCount()>0 && cursor.getCount()>0)
            {
                ColumnNames=cursor.getColumnNames();
                if (cursor.moveToFirst()){
                       do{
                           StringBuffer value= new StringBuffer();
                            value.append("{");
                           for(int i=0;i<cursor.getColumnCount();i++)
                           {
                               if(value.length()>1)
                                   value.append(", \\\""+ColumnNames[i]+"\\\":\\\"" + cursor.getString(i)+"\\\"");
                               else
                                  value.append("\\\""+ ColumnNames[i] +"\\\":\\\"" + cursor.getString(i) +"\\\"");
                           }
                           value.append(value + "}");
                           values.add(value);
                       }while(cursor.moveToNext());
                    }
                    cursor.close();
            }

Дължината на стойността StringBuffer е 4860024.


person Karthick    schedule 07.10.2013    source източник
comment
Каква е катастрофата? Можете ли да публикувате проследяването на стека?   -  person Graham Borland    schedule 07.10.2013
comment
@GrahamBorland Поставих тук информацията за logcat.   -  person Karthick    schedule 10.10.2013
comment
защо трябва да заредите цялата база данни в 1 низ наведнъж?   -  person njzk2    schedule 10.10.2013
comment
Трябва да изпълня заявката SELECT_ALL и да конвертирам курсора в json данни. Това е моето изискване. Вместо да използвам низ или stringbuffer като този, Как мога да постигна това?   -  person Karthick    schedule 10.10.2013


Отговори (1)


Е, ясно е, че просто ти свършва паметта. Вие изграждате String представяне на базата данни, като използвате поредица от неизменни String обекти.

String value="";

Всеки път, когато правите конкатенация на низ, value=value +", \\\"" вие създавате нов String обект. Това е много неефективно по отношение на използването на паметта.

Опитайте да използвате StringBuilder вместо String и използвайте неговия append() метод вместо оператора за конкатенация на низове +. Това ще позволи низът да бъде изграден в единичен буфер (който ще расте според нуждите), което го прави много по-вероятно да се побере в наличната купчина памет.

person Graham Borland    schedule 10.10.2013
comment
Разработвам приложение, което обикновено извиква родния метод чрез javascript. Това извикване на метод връща json низа на html страницата. Това е причината да имам манипулации с низове. Още едно мислене, прочетох някои въпроси, които описват, че размерът на курсора на android е 1MB. Това вярно ли е? - person Karthick; 10.10.2013
comment
Има ли предложения за този сценарий? - person Karthick; 10.10.2013
comment
Не разбирам какво питаш. Направихте ли предложените промени? Реши ли проблема? - person Graham Borland; 10.10.2013
comment
stackoverflow.com/questions/5406429/ В тази връзка те посочиха, че размерът на курсора е 1MB. Питам правилно ли е това? Имам нужда от JSON стойности на стойностите на базата данни, това е причината да използвам манипулации на низове. Опитвам се да генерирам JSON низ с помощта на stringbuilder. - person Karthick; 10.10.2013
comment
Ако публикувате повече от проследяването на стека от LogCat, това може да ни помогне да идентифицираме дали грешката при разпределението възниква в SQLite или с вашите конкатенации на низове. Във всеки случай, моля, опитайте моето предложение и ме уведомете, ако помага. - person Graham Borland; 10.10.2013
comment
Благодаря за актуализацията. Опитвам вашите предложения. Изправен пред трудности при генериране на JSON низ с конструктор на низове. Получавам един ред от грешката в logcat. - person Karthick; 10.10.2013
comment
Използвайки конструктора на низове, приложението също се срива. Поставих кода във въпросите си. - person Karthick; 10.10.2013
comment
Получавам, че дължината на stringbuffer е 4860024. Това е основната причина за срива на приложението. - person Karthick; 10.10.2013
comment
всъщност всеки приличен java компилатор трансформира конкатенация на низове в stringbuilder. - person njzk2; 10.10.2013