数据库被覆盖(必须打开应用程序两次正确显示)



LATEST:查看底部的代码,查看我的破解方案。

原文:我遵循了一些教程和例子,并去做了我自己的数据库。问题是,当我将数据库下载到手机时,它应该被读取并填充一个旋转器。我发现下载的数据库是完整的,但是当它被dbhelper读取时,它以某种方式被重写为一个空白表。我不明白为什么。

EDIT1:对不起,我应该说得更清楚些。数据库来自服务器。直接下载到/data/data/project/databases/。文件下载后我就是在那里检查的。它很好,直到我调用'DbAdapter mDbHelper = new DbAdapter(context);’之后,Android元数据表、名称表和sqlite表仍然在数据库中,列有名称,但没有条目,所以表本质上是空白的。

编辑2:(抱歉这么久)

我在下面注释了:

c = initSpinner(c);

是我写的一个方法,以防游标返回!moveToFirst()。在此方法中,创建数据库并将"add name"插入到表中。

然后我稍微玩了一下这个应用程序,这是我发现的:

当我第一次在我的设备上打开应用程序时,在一个全新的安装中,旋转器显示默认的"添加名称"。所以我添加了一个名字。我重新打开应用程序,我输入的名字就在那里,还有"添加名字"…清除所有数据并卸载后进入模拟器。打开应用程序,只有"添加一个名字"在那里。退出并重新打开,旋转器显示"添加名称"和我在手机上输入的名称……所以我在模拟器上添加了一个名称,回到我的手机,关闭并重新打开应用程序,现在有2个名称和"添加名称"…

总结:它的工作原理,但我必须重新打开应用程序后,初始安装读取数据库并正确填充旋转器。为什么?

EDIT3(最新):参见最后的代码破解解决方案…

下面是填充旋转控件的代码。

    private void fillSpinner(){
    DbAdapter mDbHelper = new DbAdapter(context);
    mDbHelper.open("names");
    Cursor c = mDbHelper.fetchAllRows();
    ArrayList<String> a = new ArrayList<String>();
    if ( c.getPosition() != 0 && c.moveToFirst() == (false) ){
//          c = initSpinner(c); //commented out to prevent creating a new     //database.
    }

是DbAdapter的代码。

public class DbAdapter {
// Database fields
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "name";
static final String DATABASE_TABLE = "names";
private Context context;
private SQLiteDatabase database;
private DbHelper dbHelper;

public DbAdapter(Context ctx) {
    context = ctx;
}
public SQLiteDatabase openToRead() throws SQLException {
    dbHelper = new DbHelper(context);
    database = dbHelper.getReadableDatabase();
    return database;
}
public SQLiteDatabase open(String dbname) throws SQLException {
    dbHelper = new DbHelper(context);
    database = dbHelper.getWritableDatabase();
    return database;
}
public void close() {
    dbHelper.close();
}
//  
/**
 * Create a new todo If the todo is successfully created return the new
 * rowId for that note, otherwise return a -1 to indicate failure.
 */
public long createRow(String name) {
    ContentValues initialValues = createContentValues(name);
    return database.insert(DATABASE_TABLE, null, initialValues);
}
public long createRowWithAL(ArrayList<String> values){
    ContentValues v = ArrayListToContentValues(values);
    return database.insert(DATABASE_TABLE, null, v);
}
private ContentValues ArrayListToContentValues(ArrayList<String> parcel){
    ContentValues values = new ContentValues();
//      values.put(KEY_ROWID, _id);
    values.put(KEY_NAME, parcel.get(0));
    return values;
}

/**
 * Update the todo
 */
public boolean updateRows(long rowId, 
        String name) {
    ContentValues updateValues = createContentValues(
            name);
    return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "="
            + rowId, null) > 0;
}

/**
 * Deletes todo
 */
public boolean deleteRow(long rowId) {
    return database.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

/**
 * Return a Cursor over the list of all todo in the database
 * 
 * @return Cursor over all notes
 */
public Cursor fetchAllRows() {
    return database.query(DATABASE_TABLE, null, null, null, null,
            null, null);
}

/**
 * Return a Cursor positioned at the defined todo
 */
public Cursor fetchRow(long rowId) throws SQLException {
    Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] {
            KEY_ROWID ,KEY_NAME},
            KEY_ROWID + "=" + rowId, null, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

private ContentValues createContentValues(String name){
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, name);
    return values;
}
//returns (an) entire column(s), all rows
public Cursor fetchColumns(String[] colnames) {
    Cursor mCursor = database.query(DATABASE_TABLE, colnames, null, 
            null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

}

下面是DbHelper的代码。

public class DbHelper extends SQLiteOpenHelper {
Context context;
private static final String DATABASE_NAME = "names";
private static final int DATABASE_VERSION = 1;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table if not exists "+DATABASE_NAME+" (_id integer primary key autoincrement, " +
    "name text not null);";
public DbHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Method is called during creation of the database
@Override
public void onCreate(SQLiteDatabase database) {
    database.execSQL(DATABASE_CREATE);
}
// Method is called during an upgrade of the database, e.g. if you increase
// the database version
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
        int newVersion) {
    Log.w(DbHelper.class.getName(),
            "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
    database.execSQL("DROP TABLE IF EXISTS names");
    onCreate(database);

}}

——黑客代码:

    private void fillSpinner(){
    DbAdapter mDbHelper = new DbAdapter(context);
    mDbHelper.open("name");
        mDbHelper.createRow("Add Name"); //added this
    mDbHelper.close();               //added this
    downloadFile();                  //added this
    mDbHelper.open("names");
    Cursor c = mDbHelper.fetchAllRows();
    ArrayList<String> a = new ArrayList<String>();
    if ( c.getPosition() != 0 && c.moveToFirst() == (false) ){
        c.close();          
        mDbHelper.createRow("Add Name");
        c = mDbHelper.fetchColumns(new String[] {"_id","name"});
    }

你说的"当我把数据库下载到手机上"是什么意思?我猜你的资产里包括了你的数据库吧?如果是这样的话……

SQLiteOpenHelper在应用程序私有内部存储中查找数据库。它将找不到数据库,因此将在内部存储中创建一个新数据库。这就是它将从中读取的数据库。

我想到的几个选项:

  1. DbHelper onCreate中创建并填充数据库(而不是像现在这样创建一个空数据库)。如果它是一个简单的小数据库,我会这样做。
  2. 从资产复制到内部存储。例如http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/

这是一个hack/workaround我发现,但为什么它的工作?

private void fillSpinner(){
DbAdapter mDbHelper = new DbAdapter(context);
mDbHelper.open("name");
    mDbHelper.createRow("Add Name"); //added this
mDbHelper.close();               //added this
downloadFile();                  //added this
mDbHelper.open("names");
Cursor c = mDbHelper.fetchAllRows();
ArrayList<String> a = new ArrayList<String>();
if ( c.getPosition() != 0 && c.moveToFirst() == (false) ){
    c.close();          
    mDbHelper.createRow("Add Name");
    c = mDbHelper.fetchColumns(new String[] {"_id","name"});
}

最新更新