Android SQLite Query, Insert, Update, Delete, всегда нужно быть в фоновом потоке?

В настоящее время я использую Loaders для захвата данных из моего ContentProvider (чтобы включить автоматическое обновление моих курсоров). Этот подход прямолинейен для запроса базы данных, хотя он, похоже, подходит для любой другой операции БД (например, "Вставка", "Обновление", "Удалить").

Мои вопросы:

  1. Должны ли все операции SQLite быть в фоновом потоке или безопасно выполнять простые операции, такие как "Вставка, обновление или удаление одной строки в потоке пользовательского интерфейса"?
  2. Что такое приятный дизайн, чтобы все запросы проходили через фоновый поток? Я хотел бы реализовать AsyncTask, должен ли я создать SuperTask так сказать, что расширяет AsyncTask и выполняет каждую операцию SQLite? (Бонус: можете ли вы представить пример с голубыми костями?)

Спасибо!

Ответ 1

Я выполнил операции SQLite в моем потоке пользовательского интерфейса. Думаю, на самом деле возникает вопрос, будут ли ваши запросы когда-либо длиться долго или нет. У меня никогда не было сбоя приложения от слишком долгого выполнения SQL-запросов в моей базе данных SQLite.

С учетом сказанного, если вы планируете писать сложные запросы, которые могут потребовать времени для загрузки, вы хотели бы запустить его как AsyncTask или Thread и использовать обратные вызовы для обновления вашего интерфейса, если это необходимо.

Это отличный учебник по SQLite на Android (он также затрагивает некоторые сложные проблемы с SQL-запросами, о которых вы говорили): http://www.vogella.com/tutorials/AndroidSQLite/article.html

Ответ 2

  1. Все операции SQLite не обязательно должны быть на фоне, но должны быть. Даже простые обновления строк могут влиять на поток пользовательского интерфейса и, следовательно, быстродействие приложений.

  2. Android включает абстрактный класс AsyncQueryHandler:

    Вспомогательный класс, помогающий упростить обработку асинхронных запросов ContentResolver.

Вот два примера реализации: Использование AsyncQueryHandler для доступа к поставщикам содержимого асинхронно в Android. Класс участника:

class MyQueryHandler extends AsyncQueryHandler {

    public MyQueryHandler(ContentResolver cr) {
        super(cr);
    }

    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        // query() completed
    }

    @Override
    protected void onInsertComplete(int token, Object cookie, Uri uri) {
        // insert() completed
    }

    @Override
    protected void onUpdateComplete(int token, Object cookie, int result) {
        // update() completed
    }

    @Override
    protected void onDeleteComplete(int token, Object cookie, int result) {
        // delete() completed
    }
}

Анонимный класс:

AsyncQueryHandler queryHandler = new AsyncQueryHandler(getContentResolver()) {
    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {

        if (cursor == null) {
            // Some providers return null if an error occurs whereas others throw an exception
        }
        else if (cursor.getCount() < 1) {
            // No matches found
        }
        else {

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

        }
    }
};

Дальнейшие подробности:

  1. Реализация AsyncQueryHandler

  2. http://www.trustydroid.com/blog/2014/10/07/using-asyncqueryhandler-with-content-provider/