0

Картина следующая:

  1. Создал базу данных.
  2. В активити есть список с едой. Если выбрать, открывается подробная информация о еде.
  3. В активити с подробной информацией есть CheckBox, который указывает, любимый напиток или нет. Если поставить галочку - запускается метод doInBackground, который обновляет файл базы данных. Вроде все хорошо. Обновление БД идет в фоновом потоке.

Вопрос. Для вывода информации я создаю Курсор и добавляю его в Адаптер. По сути, это, вроде как, такая же работа с БД, как и её обновление. Как можно сделать процесс создания Курсора в методе doInBackground, а добавление его в Адаптер в основном методе onCreate ?

Код создания с добавления Курсора в Адаптер.

SQLiteOpenHelper sqLiteOpenHelper = new Database(this);
            db = sqLiteOpenHelper.getReadableDatabase();
            cursor = db.query("DRINK",
                    new String[]{"_id", "NAME"},
                    null, null, null, null, null);
            CursorAdapter listAdapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_1,
                    cursor,
                    new String[]{"NAME"},
                    new int[]{android.R.id.text1},
                    0);
            listView.setAdapter(listAdapter);

Решение проблемы с extends FragmentActivity:

import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;

public class DrinkCategoryActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

    ListView lvData;
    //    DB db;
    SimpleCursorAdapter scAdapter;
    public SQLiteDatabase db;

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink_category);
        SQLiteOpenHelper sqLiteOpenHelper = new Database(this);
        db = sqLiteOpenHelper.getReadableDatabase();
        String[] from = new String[] {"NAME"};
        int[] to = new int[] {R.id.tvText };
        scAdapter = new SimpleCursorAdapter(this, R.layout.item, null, from, to, 0);
        lvData = (ListView) findViewById(R.id.lvData);
        lvData.setAdapter(scAdapter);
        lvData.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (l==0){
                    Toast.makeText(getApplicationContext(),"QWERTY", Toast.LENGTH_SHORT).show();
                }else if (l==1){
                    Toast.makeText(getApplicationContext(),"QWERTY",Toast.LENGTH_SHORT).show();
                }
            }
        });
        getSupportLoaderManager().initLoader(0, null, this);
    }

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bndl) {
    return new MyCursorLoader(this, db);
}

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        scAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
    }

    static class MyCursorLoader extends CursorLoader {
        SQLiteDatabase db;
        public MyCursorLoader(Context context, SQLiteDatabase db) {
            super(context);
            this.db = db;
        }

        @Override
        public Cursor loadInBackground() {

            Cursor cursor = db.query("DRINK",
                    new String[] {"_id", "NAME"},
                    "NAME = ?", new String[]{"TEST"}, null, null,null);
            return cursor;
        }

    }

}

Решение с extends Activity:

import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;

public class DrinkCategoryActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {

    ListView lvData;
    //    DB db;
    SimpleCursorAdapter scAdapter;
    public SQLiteDatabase db;

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink_category);
        SQLiteOpenHelper sqLiteOpenHelper = new Database(this);
        db = sqLiteOpenHelper.getReadableDatabase();
        String[] from = new String[] {"NAME"};
        int[] to = new int[] {R.id.tvText };
        scAdapter = new SimpleCursorAdapter(this, R.layout.item, null, from, to, 0);
        lvData = (ListView) findViewById(R.id.lvData);
        lvData.setAdapter(scAdapter);
        lvData.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (l==0){
                    Toast.makeText(getApplicationContext(),"QWERTY", Toast.LENGTH_SHORT).show();
                }else if (l==1){
                    Toast.makeText(getApplicationContext(),"QWERTY",Toast.LENGTH_SHORT).show();
                }
            }
        });
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public android.content.Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new MyCursorLoader(this, db);
    }

    @Override
    public void onLoadFinished(android.content.Loader<Cursor> loader, Cursor cursor) {
        scAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(android.content.Loader<Cursor> loader) {

    }

    static class MyCursorLoader extends android.content.CursorLoader {
        SQLiteDatabase db;
        public MyCursorLoader(Context context, SQLiteDatabase db) {
            super(context);
            this.db = db;
        }

        @Override
        public Cursor loadInBackground() {

            Cursor cursor = db.query("DRINK",
                    new String[] {"_id", "NAME"},
                    "NAME = ?", new String[]{"Latte"}, null, null,null);
            return cursor;
        }

    }
}
  • для асинхронной работы с SQLite на Android используется класс CursorLoader, а не AsyncTask/ Данный класс предоставляет все возможности для асинхронной работы с курсором (пример использования), но в наше время настоятельно рекомендуется пользоваться Architecture Components:Room, LiveData,ViewModel и тд. – pavlofff Aug 26 '18 at 14:40
  • А CursorLoader работает в фоновом потоке, если я все правильно понимаю ? – Максим Ващук Aug 26 '18 at 17:12
  • Сделал реализацию через extends FragmentActivity. Использую getSupportLoaderManager().initLoader(0, null, this);. Но когда сделаю через extends Activity, то ошибка в методе getSupportLoaderManager(). Типа, его нет. Хотел узнать, что лучше использовать в этой ситуации, FragmentActivity или Activity. И если Activity, то почему этот метод не работает. Спасибо. – Максим Ващук Aug 28 '18 at 11:18
  • в классе Activity используйте getLoaderManager(). потому что класс Activity не из библиотеки поддержки, а класс FragmentActivity из библиотеки поддержки, соответственно второму нужен метод тоже из библиотеки поддержки (support) а первому нет – pavlofff Aug 28 '18 at 12:34
  • Если я использую getLoaderManager(),то ошибка в 3-ем параметре - this. getLoaderManager().initLoader(0, null, this);.Компилятор выдает 2 решения проблемы.1.Перед "this", дописать-(LoaderManager.LoaderCallbacks). Но при этом приложение крашится. 2. Вместо implements LoaderCallbacks<Cursor> использовать implements LoaderManager.LoaderCallbacks<Cursor>, при этом, изменить существующие методы. В них Loader<Cursor> заменять на android.content.Loader<Cursor>.Но в методе @Override public Cursor loadInBackground(), в котором возвращаю cursor ошибка. Именно в слове-Override. – Максим Ващук Aug 28 '18 at 13:45
  • В описании проблемы(в основной части темы) добавлю код, который я изменил. – Максим Ващук Aug 28 '18 at 13:48
  • Прошу прощения. Вроде как, в каком-то 1 из 3-ох методов я забыл сменить Loader<Cursor> на android.content.Loader<Cursor>. Сейчас, вроде как, все работает. Спасибо еще раз. – Максим Ващук Aug 28 '18 at 13:59
  • А если я делаю вывод списка через ListActivity, к примеру, одного напитка, то выводит список, без названий. То есть, видно, что в списке что-то есть, но без названия. При нажатии переходит в аквитити с подробной информацией о напитке. При этом, в коде почти ничего не менял. Добавил только ListView listView = getListView(); и потом добавил в список адаптер. – Максим Ващук Aug 28 '18 at 14:10
  • Я конечно все понимаю но постарайтесь немного тут повисеть и перейти на ORM –  Aug 28 '18 at 14:41
  • при использовании класса Activity нужно импортировать нативные классы (из API Android) а не из библиотеки поддержки (как android.support.v4.content.CursorLoader и все другие ) – pavlofff Aug 29 '18 at 01:21

0 Answers0