Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Sqlite插入不';我不能正常工作_Java_Android_Sqlite - Fatal编程技术网

Java Sqlite插入不';我不能正常工作

Java Sqlite插入不';我不能正常工作,java,android,sqlite,Java,Android,Sqlite,第一次在这里编写Android应用程序 我的用例如下:在一个活动中,我有一个显示摘要(金额总和)的TextView,和一个带有EditText的按钮。这个想法是按下按钮向sqlite数据库添加一个条目 问题是,每次我按下按钮时,似乎输入的上一个值正在添加到数据库中 输入10->按下按钮->无反应 输入7->按按钮->按10进行汇总更改 输入3->按按钮->按7汇总更改 等等 以下是OnClickListener中使用的方法: public static void addExpense(Conte

第一次在这里编写Android应用程序

我的用例如下:在一个活动中,我有一个显示摘要(金额总和)的
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,完全同意你的观点,伙计。我知道我会因为从教程中复制代码而受到惩罚。。谢谢,这就是问题所在。这是一个很好的教训:永远不要在没有真正理解代码的情况下复制代码。它有时会造成问题,就像这次对你所做的那样,但更重要的是,它意味着你错过了学习和变得更好的机会@斯尼尔多尔科,完全同意你的意见,伙计。