I have been trying to create an utility class for my Android app, so instead of each Activity calling Room database - all of the operations would be performed in that one 'Utility' class and requested from each activity whenever and wherever needed.
I have tried to establish connection with database in the same way as within SettingsActivity (in onCreate) as well as within the corresponding class responsible for the required operation) - without any luck.
Firstly, the code for retrieving number of fares saved within the Room database from within the Activity class.
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
Code for QueriesUtility.java class:
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
*/
}
As you can tell - I've tried to establish connection with database in both ways in an act of desperation ;) (within onCreate as well as within CalcNumberOfFares). Is 'onCreate' ignored - as class is a non-Activity class?
The following is the log with the error:
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.
When calls to Room DB are performed within the Activity's class - everything works as it should.
This is how connection with Room database is established within 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();
And code for DeletingFares (which works within the SettingsActivity.java class):
/**
* 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();
}
}
As I understand the concept behind the NullPointerException - the reference to the object within QueriesUtility class (but requested from SettingsActivity class) does not exist as there is no connection to the database, hence to object is being referenced and returns null (is that correct?).
I would really appreciate if someone could point me into the right direction. Thank you so much!