Pytanie Jak wykonywać operacje na bazach danych za pomocą zadania asynchronicznego


Moja aplikacja ulega utknięciu podczas wykonywania operacji bazy danych po wyszukiwaniu w poszukiwaniu rozwiązań. Sugerowano, że używam AsyncTask, aby główny wątek nie został zablokowany.

Stworzyłem oddzielną klasę i rozszerzoną wersję SQLiteOpenHelper oraz zaimplementowałem metodę "OnCreate" i "OnUpgrade". Ale aby zaimplementować AsyncTask muszę rozszerzyć "AsyncTask". Teraz mój problem polega na tym, że rozszerzyłem już jedną klasę i nie mogę rozszerzyć innej klasy dla tej samej klasy.

Mój kod jest podobny do tego.

import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;

import com.example.project.R;

public class Database  extends SQLiteOpenHelper{

    static final String dbname="Project";
    static final int dbversion=1;

    TableA r=new TableA();


    SQLiteDatabase db;
    private Context Context;
    public Database(Context context) {
        super(context,  dbname, null, dbversion);
        try{
        db=getWritableDatabase();
        // TODO Auto-generated constructor stub
        if (db.isOpen()){

            System.out.println("Database is opened");
        }
            else{


                System.out.println("Database is not opened");
            }

        }
        catch(Exception e){

            Log.e(dbname, e.getMessage());

        }
    }


    @Override
    public void onCreate(SQLiteDatabase db) {

        // TODO Auto-generated method stub
        try{
        db.beginTransaction();

        db.execSQL(r.r_Table);


        db.insert(r.Tablename, null, r.insertdata());
        db.setTransactionSuccessful();
        retrivedata();
        }
        catch(Exception e){

            android.util.Log.e(r.Tablename, e.getMessage());

        }

        finally{

            db.endTransaction();
        }


    }//

Czy ktoś może zasugerować, w jaki sposób można wykonać operacje bazy danych za pomocą SQLiteOpenHelper w AsyncTask.

Dzięki Śiwa


16
2018-04-30 05:49


pochodzenie


Można utworzyć oddzielną klasę dla AsyncTask i wywołać metodę execute (), tworząc instancję obiektu dla AsyncTask wszędzie tam, gdzie jest to wymagane. O ile mi wiadomo, AsyncTask służy do operacji sieciowych. Nie sądzę, że jest to wymagane do uzyskania dostępu do SQlite DB. - SKK
Dzięki za odpowiedź Santosh .. ale moja aplikacja jest uderzana, gdy odbieram dane, a logcat ma "Główny wątek robi więcej pracy ... coś takiego" stąd jestem zmuszony do korzystania z klasy Async ... Masz na myśli tworzenie z Asyncową klasą i wywołać ją w Oncreate klasy bazy danych? - Siva
Nie, OnCreate SQLiteOpenHelper zostaje wywołany tylko raz podczas instalacji aplikacji. Przypuszczam, że chcesz użyć AsyncTask do pobierania danych. Po prostu utwórz oddzielną klasę AsyncTask w swojej działalności lub fragment i wywołaj funkcje w klasie rozszerzające SQLiteOpenHelper, aby uzyskać wynik. Mam nadzieję, że to było jasne. - SKK
Oznacza to, że nawet jeśli zadzwonię do mojej gorszej klasy zadań Async w mojej klasie baz danych, to główny termostat nie wejdzie na obraz i wątek wątku zostanie użyty do wykonania wymaganej operacji ... Czy moje zrozumienie jest poprawne? - Siva
jeśli wywołasz AsyncTask z klasy bazy danych, kod napisany wewnątrz doInBackground będzie działał w osobnym wątku. Kod onPostExecute i onPreexecute będzie działał w wątku UI. A wywoływanie to AsyncTask z klasy bazy danych nie ma dla mnie sensu. I to ostrzeżenie, o którym wspomniałeś, pojawia się w i po wersji Androida 4. To nie jest wielka sprawa. możesz to zignorować. jeśli potrzebujesz ogólnej struktury, daj mi znać. - SKK


Odpowiedzi:


W Twoim Actvity dodaj następujący kod, wprowadź wymagane zmiany,

private class GetContacts extends AsyncTask<Object, Object, Cursor> {
    DatabaseConnector dbConnector = new DatabaseConnector(
            getApplicationContext());

    @Override
    protected Cursor doInBackground(Object... params) {
        dbConnector.open();
        if (dbConnector.getAllValues() != null) {
            return dbConnector.getAllValues();
        } else
            return null;
    }

    @Override
    protected void onPostExecute(Cursor result) {
        if (result != null) {
            conAdapter.changeCursor(result); // set the adapter's Cursor
            dbConnector.close();
        }
    }
}

wykonaj to przez new GetContacts().execute((Object[]) null);


13
2018-04-30 06:06



Dzięki Atif .. ale to getContacts powinno zostać wywołane gdzieś w kodzie. Moje zapytanie o to, kiedy ta metoda zostanie nazwana wątkiem saperatu, zostanie użyte do wykonania lub główny wątek wykona operacje na bazie danych. - Siva
AsyncTask jest zawsze wykonywane w tle, a nie w głównym wątku, więc operacja na bazie danych będzie wykonywana w osobnym wątku. Przepraszam, jeśli nie dostałem twojego pytania. - Atif Farrukh
Chodzi mi o to, że jeśli wezwę moje zadanie Async w klasie, która jest uruchamiana przez mój główny wątek, to co się stanie? Operacje w ramach zadania Async wykonywane są przez wątek wątku lub główny wątek - Siva
@Atif Farrukh Co robi "... execute ((Object []) null);" zrobić? Versus "... execute ();" Czy to znaczy wykonać AsyncTask, jeśli obiekt nie jest pusty, inaczej po prostu wróci? - AJW
@AJW można użyć execute() zamiast execute((Object)null). To stara odpowiedź, naprawdę nie pamiętam, dlaczego to zrobiłem, prawdopodobnie wybrałem to z mojego projektu, w którym MOGĘ przekazałem argument, ale zmieniłem go tutaj w imię odpowiedzi. - Atif Farrukh


Nie, nie możesz rozszerzyć klasy z wielu klas, ponieważ narusza ona właściwość java, ponieważ java nie obsługuje wielokrotnego dziedziczenia, więc dla twojej sprawy musisz stworzyć nową klasę, która rozszerzy ASyncTask i zastąpi abstrakcyjne metody do wykonania wszystkich operacje związane z bazą danych. Dziękuję Ci


0
2018-06-22 09:20