我的项目中有两个数据库,一个附带.apk,另一个基于用户交互。现在,在第一次运行时,我想将一些数据从已发送的数据库复制到内部数据库。我有以下代码片段:
if(personalities !=null && personalities.moveToFirst()){
dbHelper.open();
do{
String name = personalities.getString(personalities.getColumnIndexOrThrow("Name"));
String displayBirthday = personalities.getString(personalities.getColumnIndexOrThrow("DOB"));
String imagePath = personalities.getString(personalities.getColumnIndexOrThrow("imageUri"));
// System.out.println("Ext Db Name: "+B+" DOB: "+C+" and imageUri: "+D);
insertAdhocCase(name,displayBirthday,imagePath, "Person", "0", FRIEND_NAME);
insertInDb(name,displayBirthday,imagePath, "Person","0", FRIEND_NAME );
}while(personalities.moveToNext());
}
但是我收到以下错误:(即使在打开与db的连接后 - dbHelper.open();)
06-04 11:27:04.897: E/AndroidRuntime(7094): FATAL EXCEPTION: AsyncTask #1
06-04 11:27:04.897: E/AndroidRuntime(7094): java.lang.RuntimeException: An error occured while executing doInBackground()
06-04 11:27:04.897: E/AndroidRuntime(7094): at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-04 11:27:04.897: E/AndroidRuntime(7094): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-04 11:27:04.897: E/AndroidRuntime(7094): at java.lang.Thread.run(Thread.java:838)
06-04 11:27:04.897: E/AndroidRuntime(7094): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.exa.digitalanniversaries/databases/Bdr
06-04 11:27:04.897: E/AndroidRuntime(7094): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
06-04 11:27:04.897: E/AndroidRuntime(7094): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1437)
06-04 11:27:04.897: E/AndroidRuntime(7094): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
06-04 11:27:04.897: E/AndroidRuntime(7094): at com.exa.digitalanniversaries.DBAdapter.insertAdhoc(DBAdapter.java:393)
06-04 11:27:04.897: E/AndroidRuntime(7094): at com.exa.digitalanniversaries.TheWizardOfOz.insertAdhocCase(TheWizardOfOz.java:738)
06-04 11:27:04.897: E/AndroidRuntime(7094): at com.exa.digitalanniversaries.TheWizardOfOz$AsyncActivity.doInBackground(TheWizardOfOz.java:644)
06-04 11:27:04.897: E/AndroidRuntime(7094): at com.exa.digitalanniversaries.TheWizardOfOz$AsyncActivity.doInBackground(TheWizardOfOz.java:1)
这样做的正确方法是什么?即使我在交易前打开数据库,为什么它会给我这个特定的错误?
答案 0 :(得分:0)
希望你不会遗漏任何内容:
答案 1 :(得分:-2)
在dbHelper.close()
语句末尾关闭数据库(do..while
),它应该可以正常工作。祝你好运!
更新:
此外,您可以在打开数据库之前使用dbHelper.isOpen()
方法,以确保您不会收到错误。
答案 2 :(得分:-2)
在DBHelper类的构造函数中,检查用户数据库是否存在,如果不存在,则将内容从apk包复制到用户数据库。请在下面找到示例代码。
/**
* Constructor
*
* @param context
* Context to be used
*/
public DBHelper(Context context) {
super(context, context.getFilesDir().getAbsolutePath() + "/database/"
+ DB_NAME, null, DB_VERSION);
mContext = context;
if (!checkDataBaseExistence())
copyDB();
}
/*
* (non-Javadoc)
*
* @see
* android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite
* .SQLiteDatabase)
*/
public void onCreate(SQLiteDatabase db) {
}
private boolean checkDataBaseExistence() {
// database to be verified
SQLiteDatabase dbToBeVerified = null;
try {
// get database path
String dbPath = mContext.getFilesDir().getAbsolutePath()
+ "/database/" + DB_NAME;
// DB_PATH + DB_NAME;
// try to open the database
dbToBeVerified = SQLiteDatabase.openDatabase(dbPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
// do nothing since the database does not exist
}
// in case it exists, close it
if (dbToBeVerified != null) {
// close DB
dbToBeVerified.close();
}
// in case there is a DB entity, the DB exists
return dbToBeVerified != null ? true : false;
}
private void copyDB() {
InputStream myInput = null;
OutputStream myOutput = null;
try {
// Open your local db as the input stream
myInput = mContext.getAssets().open("database/" + DB_NAME);
// Path to the just created empty db
File file = new File(mContext.getFilesDir().getAbsolutePath()
+ "/database");
file.mkdirs();
String outFileName = mContext.getFilesDir().getAbsolutePath()
+ "/database/" + DB_NAME;
// Open the empty db as the output stream
myOutput = new FileOutputStream(outFileName);
// transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
} catch (FileNotFoundException e) {
// handle your exception here
} catch (IOException e) {
// handle your exception here
} finally {
try {
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
} catch (Exception e) {
// handle your exception here
}
}
}