0

我正在关注 Android 上的 SQLite 教程,现在被难住了。
非常感谢您的帮助!:)

我的代码是创建一个表示厨房库存的数据库,然后相应地添加/删除项目。
我使用的类:
KitchenItem - 厨房库存项目的表示
KitchenDbHelper - 扩展 SQLiteOpenHelper,以创建 DB
KitchenDataSource - 在 DB KitchenInventoryActivity 上实际添加/删除项目
- 设置布局和初始化 KitchenDataSource

但是当我尝试运行 KitchenInventoryActivity 时,我得到一个异常:
Exception Ljava/util/MissingFormatArgumentException; 初始化 LKitchenDbHelper 时抛出;
Thais 只是 onCreate() 中我新建 KitchenDataSource 的一部分。
我想捕获更多日志,但不幸的是我无法将日志添加到构造函数。:(
我相信大部分代码是无关紧要的,但仍会在下面发布代码。
任何帮助或建议将不胜感激!

KitchenDbHelper 的代码如下:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

//creates the DB
public class KitchenDbHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "kitchen.db";
    private static final int DATABASE_VERSION = 1;
    public static final String TABLE_KITCHEN = "kitchen";

    //columns in database
    public static final String KEY_ID = "id";
    public static final String KEY_CATEGORY = "category";
    public static final String KEY_ITEM = "item";
    public static final String KEY_AMOUNT = "amount";


    private static final String DATABASE_CREATE_STATEMENT = 
            String.format("CREATE_TABLE %s ( %s INTEGER PRIMARY KEY, %s TEXT,     %s TEXT, %s TEXT;", 
                          TABLE_KITCHEN,
                          KEY_ID,
                          KEY_CATEGORY,
                          KEY_AMOUNT);

    public KitchenDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(DATABASE_CREATE_STATEMENT);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        database.execSQL("DROP TABLE IF EXISTS " + TABLE_KITCHEN);
        onCreate(database);
    }

}

KitchenItem的代码:

import android.util.Log;

//this will be used as entries into KitchenDB
public class KitchenItem {
    //TODO: this will probably be modified in the future
    private long id;
    private String category;
    private String itemName;
    private String amount;

    public KitchenItem() {

    }

    public KitchenItem(int id, String category, String itemName, int amount) {
        this.id = id;
        this.category = category;
        this.itemName = itemName;
        this.amount = Integer.toString(amount);
    }

    public KitchenItem(String itemName, int amount) {
        this.itemName = itemName;
        this.amount = Integer.toString(amount);
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = Integer.toString(amount);
    }

    @Override
    public String toString() {
        Log.d("KITCHEN", "toString in KitchenItem");
        return "itemName";
    }
}

KitchenDataSource 的代码:

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;


public class KitchenDataSource {
    private SQLiteDatabase database;
    private KitchenDbHelper dbHelper;
    private String[] allColumns = {KitchenDbHelper.KEY_ID, 
                                     KitchenDbHelper.KEY_CATEGORY,
                               KitchenDbHelper.KEY_ITEM,
                               KitchenDbHelper.KEY_AMOUNT};

    public KitchenDataSource(Context context) {
        dbHelper = new KitchenDbHelper(context);
    }

    public void open() throws SQLException {
        database = dbHelper.getWritableDatabase();
    }

    public void close() {
        dbHelper.close();
    }

    public KitchenItem addItem(KitchenItem item) {
        ContentValues values = new ContentValues();
        values.put(KitchenDbHelper.KEY_CATEGORY, item.getCategory());
        values.put(KitchenDbHelper.KEY_ITEM, item.getItemName());
        values.put(KitchenDbHelper.KEY_AMOUNT, item.getAmount());

        long insertId = database.insert(KitchenDbHelper.TABLE_KITCHEN, null, values);

        Cursor cursor = database.query(KitchenDbHelper.TABLE_KITCHEN, 
                                       allColumns, 
                                   KitchenDbHelper.KEY_ID + " = " + insertId, 
                                   null, null, null, null);

        cursor.moveToFirst();
        KitchenItem newKitchenItem = cursorToKitchenItem(cursor);
        cursor.close();

        return newKitchenItem;
    }

    public KitchenItem getItem(int id) {
        Cursor cursor = database.query(KitchenDbHelper.TABLE_KITCHEN, 
                             new String[] {allColumns[0], allColumns[1], allColumns[2], allColumns[3]},
                             KitchenDbHelper.KEY_ID + "=?", 
                             new String[] {String.valueOf(id)},
                             null, null, null, null);
        if(cursor != null) {
            cursor.moveToFirst();
        }

        KitchenItem item = new KitchenItem(Integer.parseInt(cursor.getString(0)), 
                                       cursor.getString(1), 
                                       cursor.getString(2),
                                       Integer.parseInt(cursor.getString(3)));

        cursor.close();

        return item;
    }

    public List<KitchenItem> getAllItems() {
        List<KitchenItem> itemList = new ArrayList<KitchenItem>();
        Cursor cursor = database.query(KitchenDbHelper.TABLE_KITCHEN, 
                                   allColumns, null, null, null, null, null);

        cursor.moveToFirst();
        while(!cursor.isAfterLast()) {
            KitchenItem item = cursorToKitchenItem(cursor);
            itemList.add(item);
            cursor.moveToNext();
        }
        cursor.close();

        return itemList;
    }

    public int updateItem(KitchenItem item) {       
        ContentValues values = new ContentValues();
        values.put(KitchenDbHelper.KEY_CATEGORY, item.getCategory());
        values.put(KitchenDbHelper.KEY_ITEM, item.getItemName());
        values.put(KitchenDbHelper.KEY_AMOUNT, item.getAmount());

        return database.update(KitchenDbHelper.TABLE_KITCHEN, values, KitchenDbHelper.KEY_ID + " = ?", new String[] {String.valueOf(item.getId())});
    }

    public void deleteItem(KitchenItem item) {
        long id = item.getId();
        database.delete(KitchenDbHelper.TABLE_KITCHEN, 
                    KitchenDbHelper.KEY_ID + " = " + id,
                    null);
    }

    private KitchenItem cursorToKitchenItem(Cursor cursor) {
        KitchenItem item = new KitchenItem();
        item.setId(cursor.getLong(0));
        item.setCategory(cursor.getString(1));
        item.setItemName(cursor.getString(2));
        item.setAmount(Integer.parseInt(cursor.getString(3)));

        return item;
    }
}

最后但并非最不重要的一点是 KitchenInventoryActivity:

import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;

public class KitchenInventoryActivity extends ListActivity {
    private KitchenDataSource dataSource;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d("Kitchen", "KitchenInventoryActivity onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.kitchen_inventory_activity);

        dataSource = new KitchenDataSource(this);
        Log.d("Kitchen", "dataSource initialized");
        dataSource.open();

        List<KitchenItem> itemList = dataSource.getAllItems();
        ArrayAdapter<KitchenItem> adapter = new ArrayAdapter<KitchenItem>(this, 
                                                                      android.R.layout.simple_list_item_1, 
                                                                      itemList);
        setListAdapter(adapter);
    }

    public void onClick(View clickedButton) {
        @SuppressWarnings("unchecked")
        ArrayAdapter<KitchenItem> adapter = (ArrayAdapter<KitchenItem>)getListAdapter();
        KitchenItem item = null;
        switch(clickedButton.getId()) {
        case R.id.add:
            //TODO: using a preconstructed item for now, will need to add user input
            KitchenItem tempItem = new KitchenItem("Pizza", 5);
            item = dataSource.addItem(tempItem);
            adapter.add(item);
            break;
        case R.id.delete:
            //TODO: just deleting the first item for now, will need to add selection
            if(getListAdapter().getCount() > 0) {
                item = (KitchenItem)getListAdapter().getItem(0);
                dataSource.deleteItem(item);
                adapter.remove(item);
            }
            break;
        }
        adapter.notifyDataSetChanged();
    }

    @Override
    protected void onResume() {
        dataSource.open();
        super.onResume();
    }

    @Override
    protected void onPause() {
        dataSource.close();
        super.onPause();
    }

}
4

1 回答 1

0

您的CREATE语句有五个替换字符(%s),但您只有四个变量...我假设您只是忘记了KEY_ITEM

String.format("CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s TEXT, %s TEXT, %s TEXT);", 
               TABLE_KITCHEN,
               KEY_ID,
               KEY_CATEGORY,
               KEY_ITEM,
               KEY_AMOUNT);

另外,我更改CREATE_TABLECREATE TABLE并添加了缺少的).
最后,Android 要求 Primary Key 具有 name "_id",它不会"id"...

于 2013-04-08T20:56:33.787 回答