Старый конструктор SimpleCursorAdapter устарел ... правда? - PullRequest
9 голосов
/ 31 августа 2011

Здесь говорит, что конструктор API уровня 1 SimpleCursorAdapter устарел и рекомендуется использовать LoaderManager и CursorLoader.

Но углубляясь в использование LoaderManager и CursorLoader, я нашел этот пример, где внутри внутреннего класса, который расширяет ListFragment (расширение самого фрагмента, я полагаю), мы создаем CursorLoader. Все выглядит нормально, за исключением того факта, что CursorLoader принимает Uri в качестве аргумента. Таким образом, это означает, что мне нужно создать ContentProvider, чтобы получить доступ к моей базе данных.

Должен признаться, похоже на то, что придется пройти через все это, чтобы создать простой ListView с элементами, поступающими из базы данных. Особенно, если я не собираюсь делать данные своей базы данных доступными для других приложений, и главная цель поставщика контента - сделать это.

Так это действительно того стоит?

Особенно в таких случаях, как мой, где содержимое, которое нужно извлечь, вероятно, будет небольшим. Я серьезно подумываю сделать это по-старому, что ты скажешь?

Ответы [ 5 ]

8 голосов
/ 15 сентября 2011

Я написал простой CursorLoader , который не нуждается в поставщике контента:

import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.AsyncTaskLoader;

/**
 * Used to write apps that run on platforms prior to Android 3.0. When running
 * on Android 3.0 or above, this implementation is still used; it does not try
 * to switch to the framework's implementation. See the framework SDK
 * documentation for a class overview.
 *
 * This was based on the CursorLoader class
 */
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> {
    private Cursor mCursor;

    public SimpleCursorLoader(Context context) {
        super(context);
    }

    /* Runs on a worker thread */
    @Override
    public abstract Cursor loadInBackground();

    /* Runs on the UI thread */
    @Override
    public void deliverResult(Cursor cursor) {
        if (isReset()) {
            // An async query came in while the loader is stopped
            if (cursor != null) {
                cursor.close();
            }
            return;
        }
        Cursor oldCursor = mCursor;
        mCursor = cursor;

        if (isStarted()) {
            super.deliverResult(cursor);
        }

        if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
            oldCursor.close();
        }
    }

    /**
     * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
     * will be called on the UI thread. If a previous load has been completed and is still valid
     * the result may be passed to the callbacks immediately.
     * <p/>
     * Must be called from the UI thread
     */
    @Override
    protected void onStartLoading() {
        if (mCursor != null) {
            deliverResult(mCursor);
        }
        if (takeContentChanged() || mCursor == null) {
            forceLoad();
        }
    }

    /**
     * Must be called from the UI thread
     */
    @Override
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    public void onCanceled(Cursor cursor) {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        if (mCursor != null && !mCursor.isClosed()) {
            mCursor.close();
        }
        mCursor = null;
    }
}

Ему нужен только класс AsyncTaskLoader.Либо в Android 3.0 или выше, либо в комплекте с пакетом совместимости.

4 голосов
/ 31 августа 2011

Просто используйте конструктор под ним, тот, который принимает флаги. Не используйте FLAG_AUTO_REQUERY, просто передайте 0 для флагов.

Если вам действительно не нужно обрабатывать изменения данных в базовой БД, пока пользователь просматривает ListView, вам не нужно беспокоиться о необходимости запроса.

Если, с другой стороны, вы хотите, чтобы ListView отображал изменения в БД, пока пользователь просматривает список, следуйте советам Google и используйте CursorLoader.

EDIT:

Поскольку второй конструктор доступен только в API 11, вы можете просто захотеть расширить CursorAdapter самостоятельно. Вам просто нужно реализовать bindView и newView, и все готово.

1 голос
/ 31 августа 2011

Я считаю, что CursorLoader в настоящее время предназначен для использования с ContentProvider.

Если вы хотите загрузить напрямую из вашей базы данных, используя новую платформу; Вы можете рассмотреть расширение AsyncTaskLoader и вернуть его из onCreateLoader вместо использования CursorLoader.

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

1 голос
/ 31 августа 2011

Использовать только устаревший конструктор simpleCursorAdapter. Такая ошибка появилась, когда Я разрабатывал свое приложение, но я использовал его, и оно отлично работало с моим приложением. Или попробуйте использовать конструктор ниже устаревшего на веб-сайте разработчиков Android, у которого есть дополнительный аргумент, то есть аргумент flag с ним.

0 голосов
/ 12 июня 2014

Я знаю, что этот поток старый, но вы можете просто добавить последний параметр в создание объекта SimpleCursorAdapter.Просто добавьте ", 0".

Это флаг, который нравится в Android, и предупреждение исчезнет.

Пример:

SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.item_list_layout, cursor, fromDB(), toLayout(), 0);
...