2015-11-07 102 views
1

第一次在這裏寫Android應用程序。Sqlite插入不能正常工作

我的用例如下:在一個活動中,我有一個TextView顯示一個總結(金額總和),並且ButtonEditText。這個想法是,按下按鈕添加一個條目到sqlite數據庫。

問題是,每當我按下按鈕,看起來以前的值從輸入被添加到數據庫。

  1. 輸入10 - >按按鈕 - >沒有反應
  2. 輸入7 - >按按鈕 - >摘要變化由10
  3. 輸入3 - >按按鈕 - 由>摘要變化7

下面是在OnClickListener所使用的方法:

public static void addExpense(Context ctx, Expense expense) { 
     ExpensesDbHelper dbHelper = new ExpensesDbHelper(ctx); 
     SQLiteDatabase db = dbHelper.getWritableDatabase(); 


     ContentValues values = expense.toContentValues(); 
     Log.i("Daily-", "addExpense: " + values.toString()); 

     long newRowId; 
     db.beginTransaction(); 
     try { 
      newRowId = db.insert(
        ExpensesReaderContract.ExpenseEntry.TABLE_NAME, 
        null, 
        values); 

      db.setTransactionSuccessful(); 
     } finally{ 
      db.endTransaction(); 
     } 


     Log.i("Daily-", "addExpense: new id " + newRowId); 
     Cursor c = db.rawQuery("SELECT COUNT(*) from entry", null); 
     c.moveToFirst(); 
     Log.i("Daily-", "Number of rows: " + c.getInt(0)); 
     c.close(); 

     Log.i("Daily-", "addExpense: Existing " + Expense.printable(getExpenses(db))); 
    } 

這裏的日誌語句從輸入該序列:

I/Daily-: addExpense: timestamp=2015-11-07 16:44:38 comment=Expense amount=10.0 
I/Daily-: addExpense: new id 1 
I/Daily-: Number of rows: 1 
I/Daily-: addExpense: Existing 
I/Daely-Log: 9 
I/Daily-: addExpense: timestamp=2015-11-07 16:44:41 comment=Expense amount=7.0 
I/Daily-: addExpense: new id 2 
I/Daily-: Number of rows: 2 
I/Daily-: addExpense: Existing Expense(10.000000,Expense,2015-11-07T16:44:38.000Z), 
I/Daely-Log: 9 
I/Daily-: addExpense: timestamp=2015-11-07 16:44:44 comment=Expense amount=3.0 
I/Daily-: addExpense: new id 3 
I/Daily-: Number of rows: 3 
I/Daily-: addExpense: Existing Expense(7.000000,Expense,2015-11-07T16:44:41.000Z), Expense(10.000000,Expense,2015-11-07T16:44:38.000Z), 

下面是從該活動的代碼處理事件的流程:

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_summary); 
     showAvailable(); 

     Button addExpenseButton = (Button) findViewById(R.id.add_expense); 
     final EditText amountField = (EditText) findViewById(R.id.amount); 

     addExpenseButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       try { 
        float amount = Float.parseFloat(amountField.getText().toString()); 
        addExpense(amount, "Expense"); 

        showAvailable(); 
       } catch (NumberFormatException e) { 

       } 
      } 

     }); 
    } 

現在很明顯,db.insert後返回,行仍然不是它應該在的地方。

我如何保證到getExpenses下次調用肯定會返回新行?

感謝您的幫助。

更新Expense是一個非常簡單的類:

public class Expense { 
    public static DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

    private float amount; 

    public float getAmount() { 
     return amount; 
    } 

    public String getComment() { 
     return comment; 
    } 

    public DateTime getTimestamp() { 
     return timestamp; 
    } 

    private String comment; 
    private DateTime timestamp; 

    public Expense(float amount, String comment, DateTime timestamp) { 
     this.amount = amount; 
     this.comment = comment; 
     this.timestamp = timestamp; 
    } 
    ... 
    public ContentValues toContentValues() { 
     ContentValues values = new ContentValues(); 
     values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_AMOUNT, getAmount()); 
     values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_COMMENT, getComment()); 
     values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_TIMESTAMP, iso8601Format.format(getTimestamp().toDate())); 
     return values; 
    } 
} 
+0

你能澄清這一類消費,從那裏你所得到的ContentValues對象填充,因爲很多時候,這會導致錯誤 –

+0

@PankajNimgade添加相關的代碼。正如我所提到的,整個思想的工作原理,但有一個奇怪的交易延遲。 – Anton

+0

在你的代碼,所以這不應該給你任何的滯後,你在你的情況讓你不執行任何重型任務。你可以嘗試在與UI不同的線程上執行此任務嗎?你可能想嘗試AsyncTask, –

回答

0

你的日誌表明,插入確實確實工作 - 你得到正確的COUNT(*)了,不是嗎?我會更關心Expense.printable()getExpenses()問題,但你似乎已經切出的那部分代碼,當你張貼。很可能,你在那附近的某個地方失去了一排。

如果我猜,你正在做這樣的事情在你的getExpenses()方法:

if (cursor.moveToFirst()) { 
    while(cursor.moveToNext()) { 
     <stuff> 
    } 
} 

這將使你錯過了第一排。如果這證明是您的問題,請跳過moveToFirst()調用,或者將循環更改爲do-while。

+0

我知道我會因爲複製教程中的代碼而受到懲罰..謝謝,那就是問題所在。 – Anton

+1

這是一個很好的教訓:永遠不要複製代碼而不真正理解它。它有時會導致問題,就像它這次爲你做的那樣,但更重要的是,這意味着你錯過了一個學習和變得更好的機會! –

+0

@SnildDolkow,完全符合你的隊友。 –