бесконечный цикл фоновой липкой параллельной разметки GC sqlite база данных - PullRequest
0 голосов
/ 30 декабря 2018

Я использую базу данных SQLite в приложении, я пытался добавить функцию, которая получает некоторые данные из базы данных в виде хэш-карты

 public HashMap<Integer, ArrayList<OrderCustomer>> getOrderCustomers (){
        SQLiteDatabase db = getReadableDatabase();
        String query = "SELECT * FROM " + TABLE_ORDER_CUSTOMER + " ;";
        Cursor cursor = db.rawQuery(query,null);
        cursor.moveToFirst();
        HashMap<Integer, ArrayList<OrderCustomer>> result = new HashMap<>();

        while (!cursor.isAfterLast()){
            int fkOrder = cursor.getInt(cursor.getColumnIndex(OC_FK_ORDER));
            int fkCustomer = cursor.getInt(cursor.getColumnIndex(OC_FK_CUSTOMER));
            double cost = cursor.getDouble(cursor.getColumnIndex(OC_COST));

            OrderCustomer orderCustomer = new OrderCustomer(fkOrder, fkCustomer);
            orderCustomer.setCost(cost);

            ArrayList<OrderCustomer> orderCustomers = new ArrayList<>();

            if(result.containsKey(fkOrder)){
                orderCustomers = result.get(fkOrder);
                result.remove(fkOrder);
            }
            orderCustomers.add(orderCustomer);
            result.put(fkOrder, orderCustomers);
    }
        db.close();
        cursor.close();

        return result;
}

, но так как я добавил эту функцию, приложение даетмне бесконечный цикл из следующих:

Background sticky concurrent mark sweep GC freed 133964(3MB) AllocSpace objects, 0(0B) LOS objects, 7% free, 29MB/31MB, paused 34.098ms total 149.711ms

и не запускается, а иногда он падает, OutOfMemoryError указывает на эту функцию.Что не так в функции, которая вызывает эту ошибку?PS: приложение работает нормально сразу после первой установки, это может помочь.Пожалуйста, спросите, если у вас есть дополнительная информация.

1 Ответ

0 голосов
/ 30 декабря 2018

Ваша проблема в том, что вы никогда не двигаетесь мимо первой строки, поэтому курсор никогда не будет после последней строки и, следовательно, бесконечного цикла.Это можно исправить, добавив cursor.moveToNext(); перед следующей итерацией цикла.

Однако я бы предложил использовать более простой

while(cursor.moveToNext) {
    ....... 
}

вместо использования (см. Комментарий для исправления)

cursor.moveToFirst();
while (!cursor.isAfterLast()){

    cursor.moveToNext(); // <<<<<<<<<< what was omitted
}
  • Приведенное выше может привести к сбою, если не будет извлечено ни одной строки, так как moveToFirst не проверяется на предмет успешности.

Как таковойЯ бы предложил изменить ваш код следующим образом: -

public HashMap<Integer, ArrayList<OrderCustomer>> getOrderCustomers (){
    SQLiteDatabase db = getWritableDatabase();
    String query = "SELECT * FROM " + TABLE_ORDER_CUSTOMER + " ;";
    Cursor cursor = db.rawQuery(query,null);
    HashMap<Integer, ArrayList<OrderCustomer>> result = new HashMap<>();

    while (cursor.moveToNext()){
        int fkOrder = cursor.getInt(cursor.getColumnIndex(OC_FK_ORDER));
        int fkCustomer = cursor.getInt(cursor.getColumnIndex(OC_FK_CUSTOMER));
        double cost = cursor.getDouble(cursor.getColumnIndex(OC_COST));

        OrderCustomer orderCustomer = new OrderCustomer(fkOrder, fkCustomer);
        orderCustomer.setCost(cost);

        ArrayList<OrderCustomer> orderCustomers = new ArrayList<>();

        if(result.containsKey(fkOrder)){
            orderCustomers = result.get(fkOrder);
            result.remove(fkOrder);
        }
        orderCustomers.add(orderCustomer);
        result.put(fkOrder, orderCustomers);
    }     
    cursor.close();
    db.close();
    return result;
}
  • Заметки
    • getReadableDatabase в большинстве случаев получат доступную для записи базу данных
    • cursor.moveToFirst()был удален (moveToNext переместится в первую строку, когда курсор находится в позиции перед первой строкой (т.е. -1)).
    • Курсор должен быть закрыт до закрытия базы данных
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...