Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQLite DB表在创建后不存在_Android_Android Emulator_Sqlite - Fatal编程技术网

Android SQLite DB表在创建后不存在

Android SQLite DB表在创建后不存在,android,android-emulator,sqlite,Android,Android Emulator,Sqlite,安装时,我正在将数据库文件从资产文件夹复制到数据库文件夹。我有一个名为firstRun的共享首选项,默认值为true。如果这是真的,那么我复制数据库文件并将firstRun值设置为false。紧接着这个过程,我查询数据库表中的一些数据。在较旧的Android版本(2.1)上,会发生SQLite异常(没有这样的表),应用程序会崩溃;在Android 4.2.1上,dbHelper会记录相同的消息,但会继续运行,并从它刚才找不到的表返回值。对于早期的Android版本,如果我再次启动应用程序,就会找

安装时,我正在将数据库文件从资产文件夹复制到数据库文件夹。我有一个名为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();

如果您有任何想法,我将不胜感激。

以下是工作代码的剪贴。每次加载应用程序时,我都在启动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();
}

希望这是有希望的…

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

例如:

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

希望这对其他人有所帮助。

感谢您抽出时间回复。这也正是我正在做的,所以不幸的是,它对我没有帮助。使用它,我从来没有发现db的问题。我只是简单地粘贴了一个工作示例,以便您可以尝试一下,看看您是否仍然会遇到相同的错误,如果不是,那么就很好,如果是,那么您就回到了现在的位置…尝试一下也无妨。。。