Асинхронная загрузка данных

Последнее обновление: 18.10.2021

В базе данных может быть много данных, и их загрузка может занять некоторое время. В этом случае можно воспользоваться асинхронной загрузкой данных. Для этого класс 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 данные асинхронно будут загружены из базы данных:

Content Provider in Android and Java
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850