Как правильно и правильно получить доступ к базе данных SQLite из другого потока - Android - PullRequest
0 голосов
/ 25 июня 2019

Правильный подход к доступу к базе данных.

Итак, я прочитал множество форумов о том, как получить доступ к базе данных SQLite (через SQLiteOpenHelper) - с разными ответами. По сути, у меня есть две проблемы (вопросы):

    1. Доступ к записи / чтению данных из базы данных в потоке, который не поток пользовательского интерфейса. Я использую AsyncTask, Фоновый сервис или что? Я просто пытаюсь читать или писать из базы данных и отображать результат в пользовательском интерфейсе.

        1. Должны ли простые операции чтения / записи выполняться в другом потоке? Если да, отличается ли другой используемый тип потока от используемого в вопросе 1?

          public class ReadUsers extends AsyncTask<Void, Void, List<User>> {
              public void doInBackground(Void aVoid) {
                  // Query the database here.
              }
          
              public void onPostExecute(List<User> users) {
                  // Display the data obtained here.
              }
          }
          

1 Ответ

0 голосов
/ 25 июня 2019

1) Я думаю, что AsyncTask будет работать, но у меня нет образца этого в наличии. Для чтения / записи БД SQLite я почти всегда использую Runnable (см. Пример ниже).

2) Любая операция с базой данных всегда должна выполняться в другом потоке, потому что существует реальная вероятность того, что ваш запрос займет достаточно много времени для выполнения, и ваше приложение не сможет перестать отвечать на поток пользовательского интерфейса (например, 3 секунды?) , Ключ просто не блокировать поток пользовательского интерфейса. Но тогда у вас должен быть план, когда завершится фоновая задача, как вы обновляете пользовательский интерфейс? См. Инструкцию runOnUIThread в приведенном ниже примере.

Вот пример, сначала как вызвать ваш метод:

        final Runnable searchWords = new Runnable() {
             public void run() {
                 readWords();
                }
           };

        Thread thread = new Thread(null, searchWords, "MagentoBackground");
        thread.start(); 

Тогда метод:

public void readWords() {

    Edit.listOfWords = new ArrayList<Word>();

    try {

        myDbHelper.openDataBase();

    }catch(SQLException sqle){

        throw sqle;

    }

    Cursor c = null;

    try{

        boolean containsPct = mSearch.contains("%");

        if (containsPct) {
            c = myDbHelper.searchEnableWords(mSearch);  
        } else {
            String sLength = "" + mSearch.length();
            c = myDbHelper.getEnableWords(mSearch, sLength);                    
        }

        if (c.moveToFirst())
        {

            do { 

                Word word = new Word();

                word.word = c.getString(0);
                word.length = word.word.length();
                word.value = wordValue(word.word);
                Edit.listOfWords.add(word);

            } while (c.moveToNext());
        }

        if (c != null) {
            if (!c.isClosed()) {
                c.close();
            }
        }


    } catch (Throwable t){
        Log.e("Word Assist",t.getMessage(),t);

        if (c != null) {
            if (!c.isClosed()) {
                c.close();
            }
        }

    }

    try {

        myDbHelper.close();

    }catch(SQLException sqle){

        throw sqle;

    }

    Collections.sort(Edit.listOfWords, new WordComparator());
    adapter = new WordAdapter(this, Edit.listOfWords);


    runOnUiThread(returnRes);

}

Затем делайте то, что вам нужно в потоке пользовательского интерфейса:

private Runnable returnRes = new Runnable() {
    @Override
    public void run() {

        mProgressDialog.dismiss();
        list.setAdapter(adapter);

        if (Edit.listOfWords.size() == 0) {
            empty.setVisibility(View.VISIBLE);
        } else {
            empty.setVisibility(View.GONE);
        }


    }

};

Вот пример AsyncTask:

private class GetPetDetails extends AsyncTask<String, Void, String> {
    ProgressDialog dialog;    

    @Override     
    protected void onPreExecute() {   

        dialog = new ProgressDialog(thisContext);         
        dialog.setMessage("Loading, please wait...");         
        dialog.setIndeterminate(true);         
        dialog.setCancelable(false);         
        dialog.show();     


        }

    protected String doInBackground(String... urls) {

        String animal_breed = urls[0];
        String results = "";

        try{

            results = myDbHelper.getBreedDetails(animal_breed);

        } catch (Throwable t){
            Log.e("VCAS",t.getMessage(),t);
        }

        return results;
    }

    protected void onPostExecute(String results) {
        dialog.dismiss(); 

        breedDetails = results;
        displayDetail();



    }

}// 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...