2015-11-07 180 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,完全符合你的队友。 –