我尝试使用AsyncTasks插入我的数据库。 我打电话的时候:
new insert(tableName).execute(val).get;
它按预期工作,但它会阻止UI线程。
我宁愿打电话
new insert(tableName).execute(val);
但是当我这样做时,doInBackground抛出一个SQL错误,而我传入的ContentValues是空的。 这是我的AsyncTask:
private class insert extends AsyncTask<ContentValues, Object, Long>{
String inTable;
long id = -1;
insert(TableNames table){
inTable = table.getSQL(); //This simple gets the String value TableName
}
@Override
protected void onPostExecute(Long result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.i(tag, "PostExecute: "+ inTable + " " + String.valueOf(id));
}
@Override
protected Long doInBackground(ContentValues... values) {
try {
id = getWritableDatabase().insert(inTable, null, values[0]);
} catch (SQLException e) {
e.printStackTrace();
}
return id;
}
}
在这种情况下,我并不关心他的回报价值。插入物是火,忘了它。
Log Cat:
Error inserting
android.database.sqlite.SQLiteException: near "null": syntax error (code 1): , while compiling: INSERT INTO TrackingLog(null) VALUES (NULL)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at com.westat.nopus.util.data.DataHelper$insert.doInBackground(DataHelper.java:563)
at com.westat.nopus.util.data.DataHelper$insert.doInBackground(DataHelper.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Error inserting
android.database.sqlite.SQLiteException: near "null": syntax error (code 1): , while compiling: INSERT INTO TrackingLog(null) VALUES (NULL)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at com.westat.nopus.util.data.DataHelper$insert.doInBackground(DataHelper.java:563)
at com.westat.nopus.util.data.DataHelper$insert.doInBackground(DataHelper.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
调用AsyncTask的完整方法:
void Tableinsert(TableNames tableName,ContentValues val){
val.put("Exported_Flag", "F");
if (debug) {
Log.i(tag, "TableInsert. Size: " + String.valueOf(val.size()));
//This returns 26 - Which is the correct size of the ContentValues
}
try {
new insert(tableName).execute(val); //Doesn't work
// new insert(tableName).execute(val).get; //Works
}
catch (Exception e) {
if (MyApplication.SEND_HANDLED_EXCEPTIONS) {
ACRA.getErrorReporter().handleSilentException(e);
}
e.printStackTrace();
}
}
答案 0 :(得分:0)
谢谢大家,但在阅读完评论后,我发现了我的问题。
当我创建内容值,值并将它们传递到AsyncTask时,主线程的下一行是values.clear()。显然,这会在AsyncTask将它们插入数据库之前清空值。这解释了为什么它使用了execute()。get()。
再次感谢...
答案 1 :(得分:-1)
在标题
中 private class insert extends AsyncTask<ContentValues, Object, Long>{ ...
将Long
替换为Void
,并使用
protected Long doInBackground(ContentValues... values) {
太。 现在你不再需要返回值了。