Android 使用SQLiteOpenHelper在数据库中创建表时应用程序崩溃

Android 使用SQLiteOpenHelper在数据库中创建表时应用程序崩溃,android,sqlite,crash,Android,Sqlite,Crash,我有一个应用程序,我想在ti中使用数据库。但我不能让它工作。我将提供源代码: ~tabActivity.java-->此活动扩展另一个名为deviceActivity.java的活动。Hera是一些代码片段 private DatabaseHandler DBHandler; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DBHandler = new

我有一个应用程序,我想在ti中使用数据库。但我不能让它工作。我将提供源代码:

~tabActivity.java-->此活动扩展另一个名为deviceActivity.java的活动。Hera是一些代码片段

private DatabaseHandler DBHandler;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DBHandler = new DatabaseHandler(getApplication());
}
在这个活动中,我得到了一些名称的listView和imageView。当我单击imageView时,执行此代码。在这里您可以看到,我从DBHandler类调用了方法。它返回列表

设备\状态\映像。setOnClickListener(新的OnClickListener(){

这里是DatabaseHandler.java,假设它创建数据库、两个表并填充一个表。因此,当在方法
getAlliconFoldCategory()
中出现行
SQLiteDatabase db=this.getWritableDatabase();
,它在创建时启动
onCreate
。这里是应用程序崩溃的地方。当运行命令执行查询时,它停止工作。但我不知道会出什么问题

db.execSQL(createDeviceTable);
db.execSQL(createIconTable);
这是完整的DatabaseHandler类:

public class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 4;

    // Database Name
    private static final String DATABASE_NAME = "myDatabase";

    // Table names
    private static final String TABLE_DEVICE = "device";
    private static final String TABLE_ICON = "icon";

    // Column names of device table
    private static final String ID_DEVICE = "idDevice";
    private static final String UNIT_NUMBER = "unitNumber";
    private static final String DEVICE_ID = "deviceId";
    private static final String FK_ICON = "kdIcon";

    // Colimn names of icon table
    private static final String ID_ICON = "idIcon";
    private static final String CATEGORY = "category";
    private static final String ON = "on";
    private static final String OFF = "off";
    private static final String ON_COOLING = "onCooling";
    private static final String ON_HEATING = "onHeating";
    private static final String ICON_0 = "icon0";
    private static final String ICON_10 = "icon10";
    private static final String ICON_20 = "icon20";
    private static final String ICON_25 = "icon25";
    private static final String ICON_30 = "icon30";
    private static final String ICON_40 = "icon40";
    private static final String ICON_50 = "icon50";
    private static final String ICON_60 = "icon60";
    private static final String ICON_75 = "icon75";
    private static final String ICON_80 = "icon80";
    private static final String ICON_90 = "icon90";
    private static final String ICON_100 = "icon100";

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

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createDeviceTable = "CREATE  TABLE " + TABLE_DEVICE + " ("
                + ID_DEVICE
                + " INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "
                + UNIT_NUMBER + " INTEGER NOT NULL  UNIQUE , " + DEVICE_ID
                + " INTEGER NOT NULL  UNIQUE , " + FK_ICON + " INTEGER)";

        String createIconTable = "CREATE  TABLE " + TABLE_ICON + " (" + ID_ICON
                + " INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "
                + CATEGORY + " INTEGER NOT NULL , " + ON + " TEXT, " + OFF
                + " TEXT, " + ON_COOLING + " TEXT, " + ON_HEATING + " TEXT, "
                + ICON_0 + " TEXT, " + ICON_10 + " TEXT, " + ICON_20
                + " TEXT, " + ICON_25 + " TEXT, " + ICON_30 + " TEXT, "
                + ICON_40 + " TEXT, " + ICON_50 + " TEXT, " + ICON_60
                + " TEXT, " + ICON_75 + " TEXT, " + ICON_80 + " TEXT, "
                + ICON_90 + " TEXT, " + ICON_100 + " TEXT)";

        db.execSQL(createDeviceTable);
        db.execSQL(createIconTable);

        ContentValues values = new ContentValues();
        values.put(ID_ICON, 1);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v2");
        values.put(OFF, "lightbulb_100_v2");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 2);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v1");
        values.put(OFF, "lightbulb_max_v1");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 3);
        values.put(CATEGORY, 3);
        values.put(ON, "electric_outlet_on");
        values.put(OFF, "electric_outlet_off");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        db.close();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEVICE);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ICON);

        // Create tables again
        onCreate(db);

    }

    public List<String> getAllIconsOfOldCategory(int oldCategory) {
        List<String> iconsList = new ArrayList<String>();

        String selectIconsQuery = "";
        if (oldCategory == 3)
            selectIconsQuery = "SELECT " + ON + " FROM " + TABLE_ICON;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectIconsQuery, null);

        if (cursor.moveToFirst()) {
            do {
                iconsList.add(cursor.getString(0));
            } while (cursor.moveToNext());
        }

        return iconsList;
        // return null;
    }

}

顺便说一句:如果我理解正确,当我更改数据库版本时,程序运行onUpgrade()方法,该方法删除两个表,然后调用onCreate()。当涉及到
db.close()
app崩溃时。但为什么?如果这是唯一的db.close(),数据库怎么可能已经关闭命令?如果我删除了它,应用程序就会工作。但是我认为删除它不是一个好主意,或者是真的?

代码中有一些地方看起来是错误的

首先,在TABLE_ICON create脚本中将ID_ICON设置为AUTOINCREMENT,然后在insert中显式设置ID_ICON值

其次,在GetAlliconFoldCategory方法中,仅当oldCategory==3时才设置selectIconsQuery,但无论是否设置查询,似乎都要将其传递到db.rawQuery。这肯定会导致错误


除此之外,也许您可以发布错误日志,以便我们进一步调查?

在此处发布错误日志。我更新了我的问题我更新了我的问题,并提供了错误日志。我还删除了两个字符串的自动增量。太好了。我想问题在于您在onCreate()中调用了db.close(),不需要在此处关闭。请尝试从onCreate()的结尾处删除db.close(),但请确保在GetAlliconFoldCategory()Super的结尾处关闭db!我这样做了,现在它工作了。我也在该方法的结尾处关闭了游标。因此,实际上,它是我打开数据库的方法,我必须关闭它。我会记住这一点。谢谢!
public class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 4;

    // Database Name
    private static final String DATABASE_NAME = "myDatabase";

    // Table names
    private static final String TABLE_DEVICE = "device";
    private static final String TABLE_ICON = "icon";

    // Column names of device table
    private static final String ID_DEVICE = "idDevice";
    private static final String UNIT_NUMBER = "unitNumber";
    private static final String DEVICE_ID = "deviceId";
    private static final String FK_ICON = "kdIcon";

    // Colimn names of icon table
    private static final String ID_ICON = "idIcon";
    private static final String CATEGORY = "category";
    private static final String ON = "on";
    private static final String OFF = "off";
    private static final String ON_COOLING = "onCooling";
    private static final String ON_HEATING = "onHeating";
    private static final String ICON_0 = "icon0";
    private static final String ICON_10 = "icon10";
    private static final String ICON_20 = "icon20";
    private static final String ICON_25 = "icon25";
    private static final String ICON_30 = "icon30";
    private static final String ICON_40 = "icon40";
    private static final String ICON_50 = "icon50";
    private static final String ICON_60 = "icon60";
    private static final String ICON_75 = "icon75";
    private static final String ICON_80 = "icon80";
    private static final String ICON_90 = "icon90";
    private static final String ICON_100 = "icon100";

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

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createDeviceTable = "CREATE  TABLE " + TABLE_DEVICE + " ("
                + ID_DEVICE
                + " INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "
                + UNIT_NUMBER + " INTEGER NOT NULL  UNIQUE , " + DEVICE_ID
                + " INTEGER NOT NULL  UNIQUE , " + FK_ICON + " INTEGER)";

        String createIconTable = "CREATE  TABLE " + TABLE_ICON + " (" + ID_ICON
                + " INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "
                + CATEGORY + " INTEGER NOT NULL , " + ON + " TEXT, " + OFF
                + " TEXT, " + ON_COOLING + " TEXT, " + ON_HEATING + " TEXT, "
                + ICON_0 + " TEXT, " + ICON_10 + " TEXT, " + ICON_20
                + " TEXT, " + ICON_25 + " TEXT, " + ICON_30 + " TEXT, "
                + ICON_40 + " TEXT, " + ICON_50 + " TEXT, " + ICON_60
                + " TEXT, " + ICON_75 + " TEXT, " + ICON_80 + " TEXT, "
                + ICON_90 + " TEXT, " + ICON_100 + " TEXT)";

        db.execSQL(createDeviceTable);
        db.execSQL(createIconTable);

        ContentValues values = new ContentValues();
        values.put(ID_ICON, 1);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v2");
        values.put(OFF, "lightbulb_100_v2");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 2);
        values.put(CATEGORY, 3);
        values.put(ON, "lightbulb_0_v1");
        values.put(OFF, "lightbulb_max_v1");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        values.put(ID_ICON, 3);
        values.put(CATEGORY, 3);
        values.put(ON, "electric_outlet_on");
        values.put(OFF, "electric_outlet_off");
        db.insert(TABLE_ICON, null, values);
        values.clear();

        db.close();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEVICE);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ICON);

        // Create tables again
        onCreate(db);

    }

    public List<String> getAllIconsOfOldCategory(int oldCategory) {
        List<String> iconsList = new ArrayList<String>();

        String selectIconsQuery = "";
        if (oldCategory == 3)
            selectIconsQuery = "SELECT " + ON + " FROM " + TABLE_ICON;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectIconsQuery, null);

        if (cursor.moveToFirst()) {
            do {
                iconsList.add(cursor.getString(0));
            } while (cursor.moveToNext());
        }

        return iconsList;
        // return null;
    }

}
09-15 20:07:28.539: E/AndroidRuntime(8622): FATAL EXCEPTION: main
09-15 20:07:28.539: E/AndroidRuntime(8622): java.lang.IllegalStateException: database /data/data/com.netichome.android/databases/netichome (conn# 0) already closed
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2189)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2195)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:740)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:176)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at com.netichome.mobile.backend.DatabaseHandler.getAllIconsOfOldCategory(DatabaseHandler.java:121)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at com.netichome.mobile.tabActivity$3.onClick(tabActivity.java:129)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.view.View.performClick(View.java:3549)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.view.View$PerformClick.run(View.java:14393)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.os.Handler.handleCallback(Handler.java:605)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.os.Looper.loop(Looper.java:154)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at android.app.ActivityThread.main(ActivityThread.java:4945)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at java.lang.reflect.Method.invokeNative(Native Method)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at java.lang.reflect.Method.invoke(Method.java:511)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-15 20:07:28.539: E/AndroidRuntime(8622):     at dalvik.system.NativeStart.main(Native Method)