Java Sqlite插入不';我不能正常工作
第一次在这里编写Android应用程序 我的用例如下:在一个活动中,我有一个显示摘要(金额总和)的Java Sqlite插入不';我不能正常工作,java,android,sqlite,Java,Android,Sqlite,第一次在这里编写Android应用程序 我的用例如下:在一个活动中,我有一个显示摘要(金额总和)的TextView,和一个带有EditText的按钮。这个想法是按下按钮向sqlite数据库添加一个条目 问题是,每次我按下按钮时,似乎输入的上一个值正在添加到数据库中 输入10->按下按钮->无反应 输入7->按按钮->按10进行汇总更改 输入3->按按钮->按7汇总更改 等等 以下是OnClickListener中使用的方法: public static void addExpense(Conte
TextView
,和一个带有EditText
的按钮。这个想法是按下按钮向sqlite数据库添加一个条目
问题是,每次我按下按钮时,似乎输入的上一个值正在添加到数据库中
输入10->按下按钮->无反应
输入7->按按钮->按10进行汇总更改
输入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肯定会返回新行
谢谢你的帮助
更新:费用
是一个非常简单的类:
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;
}
}
您的日志表明插入确实有效——您得到了正确的COUNT(*)
out,不是吗?我更关心的是Expense.printable()
和getExpenses()
中的问题,但您在发布时似乎删掉了这部分代码。最有可能的是,你在附近的某个地方失去了争吵
如果我猜的话,您在getExpenses()
方法中做了类似的事情:
if (cursor.moveToFirst()) {
while(cursor.moveToNext()) {
<stuff>
}
}
if(cursor.moveToFirst()){
while(cursor.moveToNext()){
}
}
那会让你错过第一排。如果这证明是您的问题,只需跳过moveToFirst()
调用,或者将循环更改为do-while。您的日志表明插入确实有效——您得到了正确的计数(*)
不是吗?我更关心的是Expense.printable()
和getExpenses()
中的问题,但您在发布时似乎删掉了这部分代码。最有可能的是,你在附近的某个地方失去了争吵
如果我猜的话,您在getExpenses()
方法中做了类似的事情:
if (cursor.moveToFirst()) {
while(cursor.moveToNext()) {
<stuff>
}
}
if(cursor.moveToFirst()){
while(cursor.moveToNext()){
}
}
那会让你错过第一排。如果这证明是您的问题,只需跳过moveToFirst()
调用,或者将循环更改为do-while。您能澄清一下这个类的开销吗?从哪里获得ContentValues对象是填充的,因为很多次这会导致error@PankajNimgade增加了相关代码。正如我所提到的,整个想法是有效的,但是有一个奇怪的事务延迟。在你的代码中,你没有执行任何繁重的任务,所以在你的情况下,这不应该给你任何延迟。您可以尝试在UI之外的单独线程上执行此任务吗。您可能想尝试AsyncTask,您能澄清一下这个类的开销吗,从哪里获得ContentValues对象是填充的,因为这会导致error@PankajNimgade增加了相关代码。正如我所提到的,整个想法是有效的,但是有一个奇怪的事务延迟。在你的代码中,你没有执行任何繁重的任务,所以在你的情况下,这不应该给你任何延迟。您可以尝试在UI之外的单独线程上执行此任务吗。您可能想尝试AsyncTask,我知道我会因为复制教程中的代码而受到惩罚。。谢谢,这就是问题所在。这是一个很好的教训:永远不要在没有真正理解代码的情况下复制代码。它有时会造成问题,就像这次对你所做的那样,但更重要的是,它意味着你错过了学习和变得更好的机会@SnildDolkow,完全同意你的观点,伙计。我知道我会因为从教程中复制代码而受到惩罚。。谢谢,这就是问题所在。这是一个很好的教训:永远不要在没有真正理解代码的情况下复制代码。它有时会造成问题,就像这次对你所做的那样,但更重要的是,它意味着你错过了学习和变得更好的机会@斯尼尔多尔科,完全同意你的意见,伙计。