Java 异步任务中的虚假事务错误
当用户单击Java 异步任务中的虚假事务错误,java,android,sqlite,android-asynctask,Java,Android,Sqlite,Android Asynctask,当用户单击btnSearch时,我在main activity中启动了一个AsyncTask的background时,我遇到了错误 这里是doInBackground的一部分,在这里我可能没有错误,可能在1个事务后出错,可能在23个事务后在记录23001处出错。在尝试insertWord之后,我得到了returnCode
btnSearch
时,我在main activity
中启动了一个AsyncTask
的background
时,我遇到了错误
这里是doInBackground
的一部分,在这里我可能没有错误,可能在1个事务后出错,可能在23个事务后在记录23001处出错。在尝试insertWord
之后,我得到了returnCode<0
private class LoadDatabase extends AsyncTask<Object, Integer, Void
{
protected Void doInBackground(Object[] params)
{
...
my_openDb("DatabaseConnector.LoadDatabase.doInBackground");
while(scDict.hasNext())
{
int kTransactions = 0;
try
{
mDatabase.beginTransaction();
while(kTransactions < MAX_TRANSACTIONS && scDict.hasNext())
{
s = scDict.next();
count++;
long returnCode = insertWord(s); // error here **********
if(returnCode < 0)
{
if(debug) Log.w("`````Abort--can't add <",s + "> at " + count + " with RC = " + returnCode + " and KT = " + kTransactions );
my_closeDb("DatabaseConnector.LoadDatabase.doInBackground DISASTER");//$$
System.exit(0);
}
++ kTransactions;
}
mDatabase.setTransactionSuccessful();
}
catch(Exception e){ Log.w("`````", "Exception " + e.toString()); }
finally
{
mDatabase.endTransaction();
publishProgress((Integer) (int) s.charAt(0));
}
}
my_closeDb("doInBackground outer while ended");
注释掉的行在过去一直有效,直到对代码进行大的修改以简化代码。(好主意。)(不是!)我是从https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
他们说的insertWithOnConflict
是将行插入数据库的通用方法
当然,我从一本教科书中得到了insert
。如前所述,这是一种将行插入数据库的方便方法。但它确实缺乏解决冲突的算法。不应该有任何冲突。当我在insert
中遇到错误时,我更改为insertWithOnConflict
这可能是我第一次警告说我的处境很艰难
我从MainActivity
调用DatabaseConnector
,它调用内部类:DatabaseHelper
,调用LoadDatabase
,然后调用doInBackground
我不确定是否应该将AsyncTask
直接连接到MainActivity
,因为答案和注释表明并发问题可能是个问题
另一个建议是将AsyncTask
放在MainActivity
中。这意味着我必须将类DatabaseConnector
及其内部类也移动到那里。如果这一切看起来过于复杂,我只是在教科书中引用了一个大例子。但是您必须将数据库连接到活动,并且您确实需要帮助,如果任务必须在后台运行,那么我理解它必须是AsyncTask
从main活动调用:
dbc = new DatabaseConnector(MainActivity.this, getAssets(), databaseFileExists());
在DatabaseConnector中:
public DatabaseConnector(Context _context, AssetManager _assets, boolean dbExists)
{
mContext = _context;
mDbOpenHelper = new DbOpenHelper(_context, DATABASE_NAME, null, 1);
SQLiteDatabase db = mDbOpenHelper.getWritableDatabase();
if( ! dbExists)
createAndOrFillDb(db);
}
createandfilldb
:
void createAndOrFillDb(SQLiteDatabase db)
{
...
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + WORD_COLUMN_NAME + " TEXT primary key );")
//...
cursor = db.query(TABLE_NAME, mColumns, null, null, null, null, WORD_COLUMN_NAME);
//...
LoadDatabase
__loadDb;
__loadDb = new LoadDatabase();
__loadDb.execute((Object[]) null);
}
所以我的问题是
(1) 您是否认为我在doInBackground
中的事务中得到了虚假的结果,因为它位于与MainActivity
不同的类中?如果是,我该怎么办
(2) 你认为我应该只在MainActivity
中插入1200行代码,这样我就不必担心并发性了,从而产生2200行的怪物吗
(3) 可能从与UI分离的线程启动doInBackground
?(不知道如何控制,但我愿意尝试。)
(4) 您还有什么建议吗?没有人要吗?认真地太久了?不清楚的?我尽了最大的努力,自上而下,逻辑性地表达出来,你知道吗?没有接受者?认真地太久了?不清楚的?我尽了最大的努力,自上而下,逻辑性地表达出来,你知道吗?
void createAndOrFillDb(SQLiteDatabase db)
{
...
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + WORD_COLUMN_NAME + " TEXT primary key );")
//...
cursor = db.query(TABLE_NAME, mColumns, null, null, null, null, WORD_COLUMN_NAME);
//...
LoadDatabase
__loadDb;
__loadDb = new LoadDatabase();
__loadDb.execute((Object[]) null);
}