NullPointerException при доступе к базе данных Room из класса Utility (не-Activity) - PullRequest
0 голосов
/ 01 февраля 2019

Я пытался создать служебный класс для своего приложения Android, поэтому вместо каждой базы данных, вызывающей активность, все операции будут выполняться в этом классе «Утилиты» и запрашиваться у каждого действия в любое время и в любом месте.

Я пытался установить соединение с базой данных таким же образом, как и внутри SettingsActivity (в onCreate), а также внутри соответствующего класса, ответственного за требуемую операцию) - безуспешно.

Во-первыхкод для получения количества тарифов, сохраненных в базе данных Room из класса Activity.

SettingsActivity.java

public void deletingFares(View view) {

// start of attempt of getting the value from QueriesUtility class

    QueriesUtility qu = new QueriesUtility();
    String quString = qu.returnNumberOfFares();

    Toast.makeText(SettingsActivity.this, 
    "Data from Queries Utilities class: (number of fares):" 
                    + quString, Toast.LENGTH_LONG).show();
// end

код класса QueriesUtility.java:

public class QueriesUtility extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_settings);

    // FARES DB
    // establishing connection with db
    mFareDAO = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "db-fares")
            .build()
            .getFareDAO();
}

public String returnNumberOfFares() {

    CalcNumberOfFares ss = new CalcNumberOfFares();
    ss.execute("");

    return numberOfFares;
}

String numberOfFares = "d0";
private FareDAO mFareDAO;
/**
 * CALCULATING NUMBER OF FARES
 */
private class CalcNumberOfFares extends AsyncTask<String, Integer, String> {

    // #1 - This is run in a background thread
    @Override
    protected String doInBackground(String... params) {
        // get the string from params, which is an array
        String myString = params[0];

        // FARES DB
        // establishing connection with db
        mFareDAO = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "db-fares")
                .build()
                .getFareDAO();

        List<Fare> fares = mFareDAO.getAllFares();

        myString = String.valueOf(fares.size());
        numberOfFares = myString;

        return myString;
    }


    // #2 - This runs in UI when background thread finishes
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        numberOfFares = result;

// todo


    }
}

/**
 *
 * END
 */
}

Как вы можете сказать - я пытался установить связь с базой данных обоими способами в отчаянии;) (в onCreate, а также в CalcNumberOfFares).Игнорируется ли 'onCreate' - так как класс не является классом Activity?

Ниже приведен журнал с ошибкой:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
              Process: com.example.android.taxidriverassistant, PID: 26280
              java.lang.RuntimeException: An error occurred while executing doInBackground()
                  at android.os.AsyncTask$3.done(AsyncTask.java:353)
                  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
                  at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:271)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
                  at java.lang.Thread.run(Thread.java:764)
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
                  at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:119)
                  at com.example.android.taxidriverassistant.QueriesUtility$CalcNumberOfFares.doInBackground(QueriesUtility.java:57)
                  at com.example.android.taxidriverassistant.QueriesUtility$CalcNumberOfFares.doInBackground(QueriesUtility.java:47)
                  at android.os.AsyncTask$2.call(AsyncTask.java:333)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
                  at java.lang.Thread.run(Thread.java:764) 
I/Process: Sending signal. PID: 26280 SIG: 9
Application terminated. 

Когда вызовы Room DB выполняются в классе Activity.- все работает как надо.

Так устанавливается соединение с базой данных Room в SettingsActivity.java:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_settings);

    // FARES DB
    // establishing connection with db
    mFareDAO = Room.databaseBuilder(this, AppDatabase.class, "db-fares")
            .build()
            .getFareDAO();

И код для DeletingFares (который работает в классе SettingsActivity.java):

    /**
 * DELETING FARES CLASS
 */
private class DeletingFares extends AsyncTask<String, Integer, String> {

    // #1 - This is run in a background thread
    @Override
    protected String doInBackground(String... params) {
        // get the string from params, which is an array
        String myString = params[0];

        List<Fare> fares = mFareDAO.getAllFares();

        myString = String.valueOf(fares.size());
        numberOfFares = myString;
        // value of myString is send over to onPostExecute and used in the end to make an Alert

        // if there are no fares - no further action should take place
        if (fares.size() > 0) {
            for (int i = 0; i < fares.size(); i++) {
                Fare ff = fares.get(i);
                mFareDAO.delete(ff);
            }
        }
        return myString;
    }


    // #2 - This runs in UI when background thread finishes
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        // invoking method which displays the alert at the end
        alertAfterDeletingFares();


    }
}

Как я понимаю концепцию NullPointerException - ссылка на объект в классе QueriesUtility (но запрашиваемая из класса SettingsActivity) не существует, так как соединение с базой данных отсутствует, следовательно, объект являетсяна меня ссылаются и возвращают ноль (это правильно?).

Я был бы очень признателен, если бы кто-то мог указать мне правильное направление.Большое вам спасибо!

1 Ответ

0 голосов
/ 01 февраля 2019

Вам нужно передать context в AsyncTask вместо использования getApplicationContext().

Ссылка getApplicationContext в классе AsyncTask?

...