I have created a basic logging class, in it currently is a 2 dimension array which stores the log information of up to 100 events (then starts over-writing the information so I only keep the last 100 events in it).
On a log event of a certain level, this array data is dumped into a database on an AsyncTask thread.
At the moment the array is defined at the class level, so the AsyncTask thread is accessing the same array that the GUI thread is accessing (which is giving me NullPointerExceptions, as it should).
I need a way to make a copy of the values of the array as it is in the instant the AsyncTask thread starts, so that this background thread can read all the data and send it to the database correctly - this is the point I'm stuck at.
// Defined in the class
private static String[][] logHistory = new String[100][6];
// Class to log errors to a database
private static class asyncLog extends AsyncTask<Void,Void,Void>
{
// This is the background thread
@Override
protected Void doInBackground(Void... params)
{
Thread.currentThread().setName("LogToDB.asyncLog.doInBackground");
// Make a copy of the array in its current state
final String[][] logTemp = new String[100][6];
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 6; j++)
{
logTemp[i][j]=logHistory[i][j];
}
}
// ...snip
}
}
Clearly the final modifier is wrong here, since I am still getting the exception
I would like to know:
- Is this the right way to do what I am trying to do?
- If not, what is a better way?
- How to have a string array copied in a background thread so that regardless of what changes the GUI thread make to the original array, the copy always has the same values until the thread ends and it is destroyed
I have seen lots of examples of coping 1D arrays, but these are mostly int data types (eg this one, and as I understand strings, they are always references :/
EDIT As requested, see stack trace:
08-23 09:17:35.570: E/AndroidRuntime(8030): FATAL EXCEPTION: LogToDB.asyncLog.doInBackground
08-23 09:17:35.570: E/AndroidRuntime(8030): java.lang.RuntimeException: An error occured while executing doInBackground()
08-23 09:17:35.570: E/AndroidRuntime(8030): at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
08-23 09:17:35.570: E/AndroidRuntime(8030): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.lang.Thread.run(Thread.java:856)
08-23 09:17:35.570: E/AndroidRuntime(8030): Caused by: java.lang.NullPointerException
08-23 09:17:35.570: E/AndroidRuntime(8030): at coty.production.downtimeaquisition.LogToDB.Insert(LogToDB.java:393)
08-23 09:17:35.570: E/AndroidRuntime(8030): at coty.production.downtimeaquisition.LogToDB.access$10(LogToDB.java:387)
08-23 09:17:35.570: E/AndroidRuntime(8030): at coty.production.downtimeaquisition.LogToDB$asyncLog.doInBackground(LogToDB.java:558)
08-23 09:17:35.570: E/AndroidRuntime(8030): at coty.production.downtimeaquisition.LogToDB$asyncLog.doInBackground(LogToDB.java:1)
08-23 09:17:35.570: E/AndroidRuntime(8030): at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-23 09:17:35.570: E/AndroidRuntime(8030): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
08-23 09:17:35.570: E/AndroidRuntime(8030): ... 4 more
LogToDB.java:558 is the call to the Insert method
LogToDB.java:387 is the Insert method
LogToDB.java:393 is the highlighted line:
Statement stmt=null;
try
{
stmt=dbConn.createStatement(); // This line
stmt.executeUpdate(sql);
}