AsyncTask中的虚假事务错误

时间:2017-09-22 17:23:23

标签: java android sqlite android-asynctask

我在尝试doInBackground AsyncTask MainActivity时遇到虚假错误,当用户点击btnSearch时,我会在doInBackground中发起错误。

这里是returnCode < 0我可能没有错误的部分,可能在1次交易后得到错误,在23次交易后可能会在记录23001处收到错误。我在尝试insertWord之后得到了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");

insertWord

方法 long insertWord(String _word) { long r = -1; ContentValues newWord = new ContentValues(); newWord.put(WORD_COLUMN_NAME, _word); try { // r = mDatabase.insert (TABLE_NAME,null,newWord); r = mDatabase.insertWithOnConflict(TABLE_NAME,null,newWord,SQLiteDatabase.CONFLICT_REPLACE); return r; } catch (Exception e) { if(debug)Log.w("DBC", "insert failed for <" + _word + ">"); if(debug)Log.w("DBC", "exception " + e.toString()); my_closeDb(DatabaseConnector.insertWord"); } return -1 ; // -1 if can't insert }

insertWithOnConflict

注释掉的行总是在过去工作,直到进行大修以简化代码。 (很棒的主意。)(不!)我从https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html得到了insertWithOnConflict的想法,他们说General method for inserting a row into the databaseinsert

当然,我从教科书中得到了convenience method for inserting a row into the database。 AS说它是insertWithOnConflict。但它确实缺乏解决冲突的算法。不应该有任何冲突。当我insert出错时,我对DatabaseConnector进行了更改。

这可能是我第一次警告我在冰上。

我从MainActivity拨打DatabaseHelper,调用内部类:LoadDatabase,调用doInBackground然后调用AsyncTask

我不确定我应该MainActivity如此直接与AsyncTask相关联,因为答案和评论表明并发问题可能是一个问题。

另一个建议是将MainActivity放在DatabaseConnector内。这意味着我也必须在那里移动类AsyncTask及其内部类。如果这一切看起来过于复杂,我只是按照教科书中的大样例。但是你必须将数据库连接到活动,你需要帮助,如果任务必须在后台运行,那么它必须是MainActivity,正如我所理解的那样。

来自dbc = new DatabaseConnector(MainActivity.this, getAssets(), databaseFileExists()); 的电话:

  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);
  }

在DatabaseConnector中:

createAndOrFillDb

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); }

doInBackground

所以我的问题是

(1)您是否认为我在MainActivity的交易中收到虚假结果,因为它与MainActivity分开,如果是,我该怎么办呢?

(2)你认为我应该将1200行代码粘贴到doInBackground中,从而产生一个2200行的怪物,所以我不必担心并发吗?

(3)也许从与UI分离的线程中启动{{1}}? (不知道如何控制,但我愿意尝试。)

(4)你还有什么建议?

0 个答案:

没有答案