我使用的是两个数据库:SYSTEM_DB1
和USER_DB1
。正在使用Android SQLiteAssetHelper将SYSTEM_DB1
从资源复制到手机记忆库。只需通过扩展USER_DB1
即可创建SQLiteOpenHelper
。
以下是代码中的一些关键点:
ATTACH
命令来使用这两个数据库
同时在我的活动中。 Db_bunduled
,以便提取旧数据然后将其删除。以下是我的活动代码:
@Override
protected void onResume() {
super.onResume();
SystemDBAssetHelper sys_db=new SystemDBAssetHelper(this);
UserDBHelper user_db = new UserDBHelper(this);
boolean b=sys_db.checkDataBase(this, USER_DATABASE_NAME_1);
Log.d(TAG, "USER_DB1 exists:"+b);
b=sys_db.checkDataBase(this, SYSTEM_DATABASE_NAME_1);
Log.d(TAG, "SYSTEM_DB1 exists:"+b);
user_db.getWritableDatabase().execSQL(
String.format("ATTACH DATABASE %s AS %s;",
SYSTEM_DATABASE_NAME_1, SYSTEM_DATABASE_NAME_1));
Log.d(TAG, "after attaching sysdb");
user_db.getWritableDatabase().execSQL(
String.format("ATTACH DATABASE %s AS %s;",
USER_DATABASE_NAME_1, USER_DATABASE_NAME_1));
Log.d(TAG, "after attaching userdb");
Cursor cursor = user_db
.getReadableDatabase()
.rawQuery(
String.format(
"SELECT * FROM %s.%s INNER JOIN %s.%s ON %s.%s = %s.%s;",
USER_DATABASE_NAME_1, TABLE_LEARNT_WORDS,
SYSTEM_DATABASE_NAME_1, TABLE_SYS_DICTIONARY,
TABLE_LEARNT_WORDS, ENTRY_ID,
TABLE_SYS_DICTIONARY, ENTRY_ID), null);
//...
user_db.close();
}
以下是SystemDBAssetHelper的代码:
public class SystemDBAssetHelper extends SQLiteAssetHelper implements Constants {
String DB_PATH;
public SystemDBAssetHelper(Context context) {
super(context, SYSTEM_DATABASE_NAME_1, null, 1);
DB_PATH= context.getApplicationInfo().dataDir +
"/databases/";
if (checkDataBase(context, DATABASE_NAME_OLD)) {
OldDbHelper oldDB = new OldDbHelper(context);
String[] currArgs = { String.valueOf(OldDbHelper.STATUS_LEARNT) };
Cursor cursor = oldDB.getReadableDatabase().query(
TABLE_SYS_DICTIONARY, null, OldDbHelper.WORD_STATUS + "=?",
currArgs, null, null, null);
//...
cursor.close();
oldDB.close();
Iterator<String> it = al.iterator();
while (it.hasNext()) {
String[] Args = { String.valueOf(it.next()) };
Cursor cursor1 = this.getReadableDatabase().query(
TABLE_SYS_DICTIONARY, null, WORD + "=?", Args, null,
null, null);
UserDBHelper user_db = new UserDBHelper(context);
//...
user_db.close();
}
}
}
public boolean checkDataBase(Context context, String DB_NAME) {
SQLiteDatabase checkDB = null;
try {
checkDB = SQLiteDatabase.openDatabase(DB_PATH+DB_NAME, null,
SQLiteDatabase.OPEN_READONLY);
} catch (Exception e) {
// e.printStackTrace();
return false;
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
}
以下是UserDBHelper的代码:
public class UserDBHelper extends SQLiteOpenHelper implements Constants {
public UserDBHelper(Context context) {
super(context, USER_DATABASE_NAME_1, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "starting oncreate in userdbhelper");
String stmt_learntWords = String.format(
"CREATE TABLE %s (%s INTEGER PRIMARY KEY, %s TEXT NOT NULL);",
TABLE_LEARNT_WORDS, _ID, ENTRY_ID);
db.execSQL(stmt_learntWords);
//...
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
//no code
}
}
以下是日志:
06-23 16:17:45.830: I/Database(2910): sqlite returned: error code = 14, msg = cannot open file at line 27205 of [42537b6056]
06-23 16:17:45.830: E/Database(2910): sqlite3_open_v2("/data/data/com.vishal.myapp/databases/Db_bunduled", &handle, 1, NULL) failed
06-23 16:17:45.830: I/Database(2910): sqlite returned: error code = 14, msg = cannot open file at line 27205 of [42537b6056]
06-23 16:17:45.830: E/Database(2910): sqlite3_open_v2("/data/data/com.vishal.myapp/databases/USER_DB1", &handle, 1, NULL) failed
06-23 16:17:45.830: D/vishal(2910): USER_DB1 exists:false
06-23 16:17:45.840: I/Database(2910): sqlite returned: error code = 14, msg = cannot open file at line 27205 of [42537b6056]
06-23 16:17:45.840: E/Database(2910): sqlite3_open_v2("/data/data/com.vishal.myapp/databases/SYSTEM_DB1", &handle, 1, NULL) failed
06-23 16:17:45.840: D/vishal(2910): SYSTEM_DB1 exists:false
06-23 16:17:45.869: D/vishal(2910): starting oncreate in userdbhelper
06-23 16:17:45.879: D/vishal(2910): ending oncreate in userdbhelper
06-23 16:17:45.889: I/Database(2910): sqlite returned: error code = 14, msg = cannot open file at line 27205 of [42537b6056]
06-23 16:17:45.889: I/Database(2910): sqlite returned: error code = 14, msg = statement aborts at 5: [ATTACH DATABASE SYSTEM_DB1 AS SYSTEM_DB1;] unable to open database: SYSTEM_DB1
06-23 16:17:45.889: E/Database(2910): Failure 14 (unable to open database: SYSTEM_DB1) on 0x225858 when executing 'ATTACH DATABASE SYSTEM_DB1 AS SYSTEM_DB1;'
06-23 16:17:45.889: D/AndroidRuntime(2910): Shutting down VM
06-23 16:17:45.889: W/dalvikvm(2910): threadid=1: thread exiting with uncaught exception (group=0x40018560)
06-23 16:17:45.899: E/AndroidRuntime(2910): FATAL EXCEPTION: main
06-23 16:17:45.899: E/AndroidRuntime(2910): java.lang.RuntimeException: Unable to resume activity {com.vishal.myapp/com.vishal.myapp.ActivityLearntWords}: android.database.sqlite.SQLiteException: unable to open database: SYSTEM_DB1: ATTACH DATABASE SYSTEM_DB1 AS SYSTEM_DB1;
//...
06-23 16:17:45.899: E/AndroidRuntime(2910): Caused by: android.database.sqlite.SQLiteException: unable to open database: SYSTEM_DB1: ATTACH DATABASE SYSTEM_DB1 AS SYSTEM_DB1;
06-23 16:17:45.899: E/AndroidRuntime(2910): at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
06-23 16:17:45.899: E/AndroidRuntime(2910): at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1763)
06-23 16:17:45.899: E/AndroidRuntime(2910): at com.vishal.myapp.ActivityLearntWords.onResume(ActivityLearntWords.java:47)
//...
以下是应用程序的... / databases /目录中的权限详细信息:
-rw-rw---- 1 app_55 app_55 8192 Jun 23 16:17 USER_DB1
-rw-rw---- 1 app_55 app_55 1024 Jun 23 16:17 webview.db
-rw-r--r-- 1 app_55 app_55 32768 Jun 23 16:17 webview.db-shm
-rw-r--r-- 1 app_55 app_55 17848 Jun 23 16:17 webview.db-wal
-rw-rw---- 1 app_55 app_55 1024 Jun 23 16:17 webviewCache.db
-rw-r--r-- 1 app_55 app_55 32768 Jun 23 16:17 webviewCache.db-shm
-rw-r--r-- 1 app_55 app_55 20992 Jun 23 16:17 webviewCache.db-wal
答案 0 :(得分:0)
我试图访问尚未在活动中创建的数据库。
user_db.getWritableDatabase().execSQL(
String.format("ATTACH DATABASE %s AS %s;",
SYSTEM_DATABASE_NAME_1, SYSTEM_DATABASE_NAME_1));
仅通过调用构造函数不会创建数据库文件。我必须在任何其他数据库相关操作之前先调用sys_db.getWritableDatabase()
。
另外,从official documentation开始,我知道原来的表格被称为“主要&#39;”。
为避免混淆,请点击此处查看最终代码:
@Override
protected void onResume() {
super.onResume();
SystemDBAssetHelper sys_db = new SystemDBAssetHelper(this);
sys_db.getWritableDatabase();
sys_db.close();
String FIRST_DB_PATH = this.getDatabasePath(SYSTEM_DATABASE_NAME_1)
.toString();
UserDBHelper user_db = new UserDBHelper(this);
user_db.getWritableDatabase().execSQL(
String.format("ATTACH DATABASE '%s' AS %s;", FIRST_DB_PATH,
SYSTEM_DATABASE_NAME_1));
Cursor cursor = user_db
.getReadableDatabase()
.rawQuery(
String.format(
"SELECT * FROM %s.%s INNER JOIN %s.%s ON %s.%s = %s.%s;",
"main", TABLE_USER,
SYSTEM_DATABASE_NAME_1, TABLE_SYS,
TABLE_USER, ENTRY_ID,
TABLE_SYS, ENTRY_ID), null);
//...
cursor.close();
user_db.close();
}