【问题标题】:Can't create SQLite database in my android app无法在我的 Android 应用程序中创建 SQLite 数据库
【发布时间】:2013-04-20 02:21:01
【问题描述】:

我正在使用我的应用程序对象(Android 构建块)在我的 oncreate 方法中调用数据库构造函数。 但我不知道为什么不能创建它。 这就是我的代码的样子:

我的数据库类,将 DbHelper 作为内部类:

package com.example.pharmacie;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class PhData {
    private static final String TAG = PhData.class.getSimpleName();

    private static final int VERSION = 1;
    private static final String DATABASE = "ph_info.db";
    private static final String TABLE = "ph_info";

    public static final String C_ID = "_id";
    public static final String C_CREATED_AT = "created_at";
    public static final String C_NAME = "Pharmacie ";
    public static final String C_TELE = " ";
    public static final String C_ADRESS = "Tet";
    public static final String C_HAS_SHIFT = "yes"; // yes if night shift
    public static final String C_SCHEDULE = "YYYY-MM-DD";

    private static final String GET_ALL_ORDER_BY = C_CREATED_AT + " DESC";
    private static final String[] MAX_CREATED_AT_COLUMNS = { "max("
            + PhData.C_CREATED_AT + ")" };    
    Context context;
    private DbHelper dbHelper;

    // Inner class: DbHelper implementations 
    class DbHelper extends SQLiteOpenHelper {

        public DbHelper() {
            super(context, DATABASE, null, VERSION);
            Log.d(TAG, "Constructor called");
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "Creating database: " + DATABASE);

            db.execSQL("create table " + TABLE + " (" + C_ID
                    + " int primary key, " + C_CREATED_AT + " int, " + C_NAME
                    + " text, " + C_ADRESS + " text, "
                    + C_HAS_SHIFT + " text, " + C_SCHEDULE
                    + " text, " + C_TELE + " text)");

            Log.d(TAG, "database created");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("drop table " + TABLE);
            this.onCreate(db);
        }
    } // end of dbhelper class


    public PhData(Context context) {
        this.context = context;
        this.dbHelper = new DbHelper();
        Log.d(TAG, "Initialized data");
    }

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

    public void insertOrIgnore(ContentValues values) {
        Log.d(TAG, "insertOrIgnore on " + values);
        SQLiteDatabase db = this.dbHelper.getWritableDatabase();
        try {
            db.insertWithOnConflict(TABLE, null, values,
                    SQLiteDatabase.CONFLICT_IGNORE);
        } finally {
            db.close();
        }
    }

    /**
     * Deletes ALL the data
     */
    public void delete() {
        // Open Database
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        // Delete the data
        db.delete(TABLE, null, null);

        // Close Database
        db.close();
    }
}

这是我的应用程序类,我在其中调用构造函数来创建我的数据库:

package com.example.pharmacie;

import android.app.Application; import android.util.Log;

public class PharmacieApplication extends Application {
          private static final String TAG = PharmacieApplication.class.getSimpleName();       PhData phData;

    @Override   public void onCreate() {        super.onCreate();
        phData = new PhData(this);
        Log.d(TAG, "onCreated");    }

    @Override   public void onTerminate() {         super.onTerminate();
        Log.d(TAG, "onTerminated");     }

}

这就是我在 logcat 中得到的:

04-20 03:15:05.968: D/PhData(368): Constructor called
04-20 03:15:05.968: D/PhData(368): Initialized data
04-20 03:15:05.968: D/PharmacieApplication(368): onCreated
04-20 03:15:06.568: D/JoursListActivity(368): onCreated

【问题讨论】:

  • 如果在之前的测试中尚未创建数据库,您是否已签入系统文件?

标签: android sqlite android-sqlite oncreate


【解决方案1】:

在您请求访问数据库之前,不会实际创建数据库。来自documentation

创建一个帮助对象来创建、打开和/或管理数据库。这 方法总是很快返回。数据库实际上不是 创建或打开直到 getWritableDatabase() 或 getReadableDatabase() 被调用。

【讨论】:

  • 我的助手对象是 PhData 类的内部类,或者你的意思是我必须在我的数据库中插入一些东西来触发 oncreate 方法?
  • @SFN 没错!具体来说,您必须致电getReadableDatabase()getWritableDatabase()。我不相信你实际上不必对它做任何事情。
【解决方案2】:

我正在更改您的代码,请输入此代码并尝试。

public class PhData {
    private static final String TAG = PhData.class.getSimpleName();

    private static final int VERSION = 1;
    private static final String DATABASE = "ph_info.db";
    private static final String TABLE = "ph_info";

    public static final String C_ID = "_id";
    public static final String C_CREATED_AT = "created_at";
    public static final String C_NAME = "Pharmacie ";
    public static final String C_TELE = " ";
    public static final String C_ADRESS = "Tet";
    public static final String C_HAS_SHIFT = "yes"; // yes if night shift
    public static final String C_SCHEDULE = "YYYY-MM-DD";

    private static final String GET_ALL_ORDER_BY = C_CREATED_AT + " DESC";
    private static final String[] MAX_CREATED_AT_COLUMNS = { "max("
            + PhData.C_CREATED_AT + ")" };    
    Context context;
    private DbHelper dbHelper;
    private SQLiteDatabase db;

    // Inner class: DbHelper implementations 
    class DbHelper extends SQLiteOpenHelper {

        public DbHelper() {
            super(context, DATABASE, null, VERSION);
            Log.d(TAG, "Constructor called");
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "Creating database: " + DATABASE);

            db.execSQL("create table " + TABLE + " (" + C_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    C_CREATED_AT + " TEXT, " + 
                    C_NAME + " text, " +
                    C_ADRESS + " text, " + 
                    C_HAS_SHIFT + " text, " +
                    C_SCHEDULE + " text, " + 
                    C_TELE + " text)");

            Log.d(TAG, "database created");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("drop table " + TABLE);
            onCreate(db);
        }
    } // end of dbhelper class


    public PhData(Context context) {
        this.context = context;
        this.dbHelper = new DbHelper(context);
        db=this.dbHelper.getWritableDatabase();
        db=this.dbHelper.getReadableDatabase();
        Log.d(TAG, "Initialized data");
    }

    public void close() {
        if (db != null)
            db.close();
    }

    public Database open() throws SQLException{
        this.dbHelper= new ContactsDBHelper(con);
        db=this.dbHelper.getWritableDatabase();
        db=this.dbHelper.getReadableDatabase();
        return this;
    }   

    public void insertOrIgnore(ContentValues values) {
        Log.d(TAG, "insertOrIgnore on " + values);
        SQLiteDatabase db = this.dbHelper.getWritableDatabase();
        try {
            db.insertWithOnConflict(TABLE, null, values,
                    SQLiteDatabase.CONFLICT_IGNORE);
        } finally {
            db.close();
        }
    }

    /**
     * Deletes ALL the data
     */
    public void delete() {
        // Open Database
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        // Delete the data
        db.delete(TABLE, null, null);

        // Close Database
        db.close();
    }
}

可能对你有帮助。

【讨论】:

    【解决方案3】:

    实际上我已经找到了导致我另一个问题的源头问题: 我必须将 dbHelper 的上下文传递到构造函数中才能从我的 Application 类中调用它。

    产生的另一个错误是这样的:

    public static final String C_SCHEDULE = "YYYY-MM-DD";
    

    您不能在创建数据库时使用减号作为分隔符,因为虚拟机将其视为数学符号。所以我的声明必须改为:

    public static final String C_SCHEDULE = "YYYY_MM_DD";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 2014-12-14
      相关资源
      最近更新 更多