创建后,Android SQLite DB表不存在

时间:2013-02-13 12:26:30

标签: android android-emulator sqlite

我正在将资产文件夹中的数据库文件复制到安装时的数据库文件夹中。我有一个名为firstRun的共享首选项,默认值为true。如果是这样,那么我复制数据库文件并将firstRun值设置为false。紧接着这个过程,我然后在数据库表中查询一些数据。在较旧的Android版本(2.1)上发生SQLite异常(没有这样的表)并且应用程序崩溃,在Android 4.2.1上,dbHelper记录相同的消息但继续运行并返回它刚刚找不到的表中的值。对于早期的Android版本,如果我再次启动应用程序,则会找到数据库表并且所有操作都会正常进行。应用程序崩溃后,我可以检查复制的数据库,表和行是否存在。这似乎与其他表格确实不存在的问题不同,因为我可以看到它们确实存在。我想知道是否存在某种同步问题,其中表在复制过程之后不会立即存在,但在某个过程完成时确实存在。据我所知,这不是异步完成的,所以我不确定原因。

以下是一些显示问题的代码:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean firstRun = prefs.getBoolean(getString(R.string.first_time_run), true);

if (firstRun) {
    SharedPreferences.Editor edit = prefs.edit();
    edit.putBoolean(getString(R.string.first_time_run), Boolean.FALSE);
    edit.commit();

    try {
        dbHelper.createDatabase();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}
// This method will fire an exception the first time the app is run - no such table
Bundle metaData = dbHelper.fetchAppMetaData();
this.appTitle = metaData.getString("app_title");
this.normalId = Integer.parseInt(metaData.getString("normal_id"));

fetchAppMetaData方法是一个基本的sqlite.query:

Bundle metaData = new Bundle();
Cursor dbCursor = null;
SQLiteDatabase database = getReadableDatabase();
String[] cols = new String[] {"app_title", "normal_id"};
dbCursor = database.query(true, TBL_METADATA, cols, null, null, null, null, null, null);  

if (dbCursor != null) {  
        dbCursor.moveToFirst();

最终会返回一个包。

数据库创建方法是:

//Open the local db as the input stream
InputStream dbFromAssets = myContext.getAssets().open(DB_NAME);

// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;

// Check that the directory now exists
File f = new File(DB_PATH);

if (!f.exists()) {
    f.mkdir();
}

// Open the empty db as the output stream
OutputStream appDatabase = new FileOutputStream(outFileName);

// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = dbFromAssets.read(buffer)) > 0){
    appDatabase.write(buffer, 0, length);
}

// Close the streams - don't cross them!
appDatabase.flush();
appDatabase.close();
dbFromAssets.close();

请感谢任何想法。

2 个答案:

答案 0 :(得分:0)

以下是工作代码的剪切和粘贴。每次应用程序加载时,我都会在MainActivity的启动时使用它。测试并使用版本2.3 - 4.2:

以下是我正在使用的代码:

try 
    {           
        String destPath = "/data/data/" + getPackageName() + "/databases/(...your db...)";

        File f = new File(destPath);  
        File c = new File("/data/data/" + getPackageName() + "/databases/");

        // ---if directory doesn't exist then create it---
        if (!c.exists()) 
        { 
            c.mkdir();
        }

        // ---if db file doesn't exist then create it---
        if (!f.exists()) 
        { 
            CopyDB(getBaseContext().getAssets().open("...name of db from assets foleder..."), new FileOutputStream(destPath));
        }
    } 
    catch (FileNotFoundException e) 
    {           
        e.printStackTrace();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }

以下是我正在使用的代码,如果找不到则进行复制:

public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException 
{
    //---copy 1K bytes at a time---
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) > 0) 
    {
        outputStream.write(buffer, 0, length);
    }

    inputStream.close();
    outputStream.close();
}

希望这是有希望的......

答案 1 :(得分:0)

我的解决方案是在创建数据库之后和我再次尝试使用之前关闭dbHelper。

例如:

try {
    dbHelper.createDatabase();
} catch (Exception e) {
}
dbHelper.close();
dbHelper.fetchAppMetaData();

希望这有助于其他人。