Intereting Posts
Перемещение блока между минимальным значением и максимальным значением в NumberPicker Неверный запросКод в onActivityResult Обнаружение жестов на фрагменте Изменение стиля CalendarView Выполнение задания каждые несколько часов Будет ли обработчик PostDelayed не запускаться, когда процессор спит? Как найти браузер по умолчанию на Android-устройстве Как добавить инструмент для android tools в путь к 7 оконному файлу? Как приостановить и возобновить поток surfaceView Есть ли хорошие ORM (желательно JPA-реализации), поддерживающие SQLite (на Android)? Просеивание arround textview с девятью фоном патча не имеет визуального эффекта Определите строку в градиенте, а также используйте приложение, специфичное для вкуса. Чтение и запись разрешений для хранения и использования галерей для зефира Android-эмулятор-5554 в автономном режиме Масштабирование макета андроида с фиксированным соотношением сторон на разных телефонах

Каковы преимущества CursorLoaders?

Я интенсивно использую Cursors в своем приложении, чтобы загружать и иногда писать информацию из базы данных и в нее. Я видел, что Honeycomb и пакет совместимости имеют новые классы Loader предназначенные для загрузки данных «хорошим» способом.

По сути, эти новые классы (в частности, CursorLoader ) значительно лучше, чем предыдущие методы управления данными? В чем преимущество CursorLoader над управляемыми Cursors например?

И я использую ContentProvider для обработки данных, что, очевидно, берет Uris но как это initLoader() методом initLoader() ? Должен ли я настроить каждый из моих Fragments для использования Loaders отдельно? И насколько уникальным должен быть идентификатор для каждого загрузчика, находится ли он в области моего приложения или всего лишь фрагмента? Есть ли простой способ просто передать Uri в CursorLoader для запроса моих данных?

Все, что я вижу на данный момент, это то, что Loaders добавляет лишний дополнительный шаг для ввода моих данных в мое приложение, так что может кто-нибудь объяснить их мне лучше?

Solutions Collecting From Web of "Каковы преимущества CursorLoaders?"

Существует два ключевых преимущества использования CursorLoader в вашем приложении над Activity.managedQuery() :

  1. Запрос обрабатывается в фоновом потоке для вас (благодаря использованию AsyncTaskLoader ), поэтому большие запросы данных не блокируют пользовательский интерфейс. Это то, что рекомендовали документы для себя при использовании обычного Cursor , но теперь это делается под капотом.
  2. CursorLoader автоматически обновляет. В дополнение к выполнению первоначального запроса CursorLoader регистрирует ContentObserver с запрошенным набором данных и вызывает forceLoad() сам по себе, когда набор данных изменяется. Это приводит к получению асинхронных обратных вызовов в любое время при изменении данных для обновления представления.

Каждый экземпляр Loader также обрабатывается через особый LoaderManager , поэтому вам все равно не нужно управлять курсором напрямую, и теперь соединение может сохраняться даже за пределами одного Activity . LoaderManager.initLoader() и LoaderManager.restartLoader() позволяют повторно подключаться к существующему Loader уже настроенному для вашего запроса, и в некоторых случаях мгновенно получать последние данные, если они доступны.

В вашей Activity или Fragment теперь будет реализован интерфейс LoaderManager.Callback . Вызов initLoader() приведет к onCreateLoader() котором вы будете строить запрос и новый экземпляр CursorLoader , если это необходимо. Метод onLoadFinished() будет onLoadFinished() каждый раз, когда будут доступны новые данные, и будет включать в себя последний Cursor для подключения к просмотру или в противном случае.

Кроме того, есть довольно хороший пример всего этого, LoaderManager странице документации класса LoaderManager : http://developer.android.com/reference/android/app/LoaderManager.html

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

Если кто-то окажется в подобной ситуации, вот что я сделал:

  • Создал класс, который реализует LoaderCallbacks и обрабатывает все запросы, которые вам понадобятся.
  • Поставьте это с помощью Context и соответствующего Adapter .
  • Создайте уникальные идентификаторы для каждого запроса, который вы будете использовать (если вы используете UriMatcher , также можете использовать одни и те же)
  • Сделайте удобный метод, который передает запросы в пакет, необходимый для LoaderCallbacks
  • Это в значительной степени это 🙂 Я поместил часть своего кода ниже, чтобы показать, что именно я сделал

В моем классе GlobalCallbacks :

 public static final String PROJECTION = "projection"; public static final String SELECTION = "select"; public static final String SELECTARGS = "sargs"; public static final String SORT = "sort"; Context mContext; SimpleCursorAdapter mAdapter; public GlobalCallbacks(Context context, SimpleCursorAdapter adapter) { mContext = context; mAdapter = adapter; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Uri contentUri = AbsProvider.customIntMatch(id); if (contentUri != null) { return new CursorLoader(mContext, contentUri, args.getStringArray(PROJECTION), args.getString(SELECTION), args.getStringArray(SELECTARGS), args.getString(SORT)); } else return null; } @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { mAdapter.swapCursor(arg1); } @Override public void onLoaderReset(Loader<Cursor> arg0) { mAdapter.swapCursor(null); } 

И когда я хотел использовать CursorLoader ( Helper.bundleArgs() – метод объединения удобства):

 scAdapt = new Adapters.NewIndexedAdapter(mHost, getMenuType(), null, new String[] { "name" }, new int[] { android.R.id.text1 }); getLoaderManager().initLoader( GlobalCallbacks.GROUP, Helper.bundleArgs(new String[] { "_id", "name" }), new GlobalCallbacks(mHost, scAdapt)); setListAdapter(scAdapt); 

И в Помощнике:

 public static Bundle bundleArgs(String[] projection, String selection, String[] selectionArgs) { Bundle b = new Bundle(); b.putStringArray(GlobalCallbacks.PROJECTION, projection); b.putString(GlobalCallbacks.SELECTION, selection); b.putStringArray(GlobalCallbacks.SELECTARGS, selectionArgs); return b; } 

Надеюсь, это поможет кому-то еще 🙂

РЕДАКТИРОВАТЬ

Чтобы более подробно объяснить:

  • Во-первых, инициализируется адаптер с нулевым Cursor . Мы не снабжаем его Cursor потому что GlobalCallbacks даст адаптеру правильный Cursor в onLoadFinished(..)
  • Затем мы говорим LoaderManager мы хотим инициализировать новый CursorLoader . Мы поставляем новый экземпляр GlobalCallbacks (который реализует Loader.Callbacks ), который затем контролирует загрузку курсора. Мы также должны снабдить его адаптером, чтобы он мог поменять местами новый Cursor после его полной загрузки. В какой-то момент LoaderManager (который встроен в ОС) вызовет onCreateLoader(..) GlobalCallbacks и начнет асинхронную загрузку данных
  • Helper.bundleArgs(..) просто помещает аргументы для запроса в Bundle (например, проекция столбцов, порядок сортировки, предложение WHERE)
  • Затем мы устанавливаем ListAdapter . Курсор по-прежнему будет пустым в этой точке, поэтому он покажет знак загрузки или пустое сообщение до onLoadFinished() пор, пока не onLoadFinished()