我创建了一个基本的日志记录类,目前它是一个二维数组,最多存储 100 个事件的日志信息(然后开始覆盖信息,所以我只保留最后 100 个事件)。
在某个级别的日志事件中,此数组数据被转储到 AsyncTask 线程上的数据库中。
目前该数组是在类级别定义的,因此 AsyncTask 线程正在访问 GUI 线程正在访问的同一个数组(这给了我 NullPointerExceptions,应该如此)。
我需要一种方法来复制数组的值,因为它是在 AsyncTask 线程启动的那一刻,以便这个后台线程可以读取所有数据并将其正确发送到数据库 - 这就是我的重点卡在。
// 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
}
}
显然final修饰符在这里是错误的,因为我仍然遇到异常
我想知道:
- 这是做我想做的事情的正确方法吗?
- 如果没有,有什么更好的方法?
- 如何在后台线程中复制字符串数组,以便无论 GUI 线程对原始数组进行什么更改,副本始终具有相同的值,直到线程结束并被销毁
我见过很多处理一维数组的例子,但这些大多是 int 数据类型(例如这个,据我了解字符串,它们总是引用:/
编辑根据要求,请参阅堆栈跟踪:
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 是对 Insert 方法的调用
LogToDB.java:387 是插入方法
LogToDB.java:393 是突出显示的行:
Statement stmt=null;
try
{
stmt=dbConn.createStatement(); // This line
stmt.executeUpdate(sql);
}