В базе данных может быть много данных, и их загрузка может занять некоторое время. В этом случае можно воспользоваться асинхронной загрузкой данных. Для этого класс activity или фрагмента должен реализовать интерфейс LoaderManager.LoaderCallbacks<Cursor>.
Возьмем проект из прошлой темы, где реализован провайдер контента AppProvider, и изменим класс MainActivity:
package com.example.friendsproviderapp; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.loader.app.LoaderManager; import androidx.loader.content.CursorLoader; import androidx.loader.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.util.Log; import java.security.InvalidParameterException; public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private static final String TAG = "MainActivity"; private static final int LOADER_ID = 225; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); // запускаем загрузку данных через провайдер контента LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this); } @NonNull @Override public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) { String[] projection = { FriendsContract.Columns._ID, FriendsContract.Columns.NAME, FriendsContract.Columns.EMAIL, FriendsContract.Columns.PHONE }; if(id == LOADER_ID) return new CursorLoader(this, FriendsContract.CONTENT_URI, projection, null, null, FriendsContract.Columns.NAME); else throw new InvalidParameterException("Invalid loader id"); } @Override public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) { if(data != null){ Log.d(TAG, "count: " + data.getCount()); // перебор элементов while(data.moveToNext()){ for(int i=0; i < data.getColumnCount(); i++){ Log.d(TAG, data.getColumnName(i) + " : " + data.getString(i)); } Log.d(TAG, "========================="); } data.close(); } else{ Log.d(TAG, "Cursor is null"); } } @Override public void onLoaderReset(@NonNull Loader<Cursor> loader) { Log.d(TAG, "onLoaderReset..."); } }
Интерфейс LoaderManager.LoaderCallbacks<Cursor> предполагает реализацию трех методов. Метод onCreateLoader()
загружает курсор.
В этот метод в качестве параметров передаются числовой код операции и объект Bundle. Числовой код передается при запуске загрузки курсора. В данном случае в качестве
такого кода использует константа LOADER_ID.
В самом методе создается объект CursorLoader. В его конструктор передается несколько параметров:
объект Context (текущая activity)
набор столбцов, которые надо получить
выражение для выборки данных
значения для параметров для выражения выборки
столбец, по которому идет сортировка
Метод onLoadFinished
вызывается при загрузке курсора. Через второй параметр мы можем собственно получить курсор и через него загруженные данные.
И соответственно в этом методе мы может перебрать курсор, получить данные и вывести их в элементах графического интерфейса или на консоль.
И метод onLoaderReset
предназначен для сброса загрузчика.
Чтобы запустить загрузку данных, в методе onCreate вызывается метод LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this);
.
Первый параметр - числовой код, а второй - объект Bundle. Это те значения, которые мы можем получить в методе onCreateLoader. И третий - объект Context.
В итоге при запуске MainActivity данные асинхронно будут загружены из базы данных: