- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经在我的 Assets 文件夹中添加了 sqlite 文件,并在我的应用程序中使用了 sqlite 文件中的数据。它在 API 27(即牛轧糖)之前运行良好。但是该应用程序因 Android Pie 即 API 28 而崩溃。我通过以下方式在我的数据库帮助程序类中使用以下方法。请帮帮我。
public Database(Context context, String databaseName) {
super(context, databaseName, null, DATABASE_VERSION);
this.context = context;
String packageName = context.getPackageName();
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
DB_NAME = databaseName;
openDataBase();
}
public void createDataBase() {
boolean dbExist = checkDataBase();
if (!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Log.e(this.getClass().toString(), "Copying error");
throw new Error("Error copying database!");
}
}else{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DB_NAME);
if (dbFile.delete()) {
database.deleteDatabase(new File(DB_PATH + DB_NAME));
openDataBase();
}
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String path = DB_PATH + DB_NAME;
//checkDb = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
checkDb = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLException e) {
Log.d(TAG, "Error while checking db");
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null;
}
private void copyDataBase() throws IOException {
InputStream externalDbStream = context.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream localDbStream = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = externalDbStream.read(buffer)) > 0) {
localDbStream.write(buffer, 0, bytesRead);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.commit();
localDbStream.close();
externalDbStream.close();
}
public SQLiteDatabase openDataBase() throws SQLException {
String path = DB_PATH + DB_NAME;
if (database == null) {
createDataBase();
database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
}
return database;
}
这些是我正在使用的 openDatabase、copyDatabase 和创建数据库方法。
这是崩溃日志 -
android.database.sqlite.SQLiteException: no such table: quran_chapters (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM quran_chapters at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58) at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408) at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1347)
最佳答案
如果数据库不存在,您将使用 this.getReadableDatabase(); 创建数据库,因为您可能在 onCreate 方法中未执行任何操作,数据库为空。
然后您用副本覆盖磁盘,但是由于数据库仍处于打开状态(通过 this.getReadableDatabase();
),空的、无表的数据库可能会完全保留在缓存中,因此会出现问题。
使用一种在数据库不存在时打开数据库的方法似乎是试图解决当它是第一个数据库时复制失败并且在那个阶段应用程序的存储没有名为 databases 的目录(打开它会创建目录)。
我个人更喜欢,并且没有遇到任何问题:-
mDBPath = context.getDatabasePath(database).getPath();
检查数据库文件是否存在是为了查看数据库是否存在,而不是打开数据库查看是否存在。 (见示例3)
检查数据库的父级(即数据库文件夹)以查看它是否存在,如果不存在,则使用文件的 mkdirs 方法创建数据库目录。例如:-
private boolean ifDatabaseExists(String dbpath) {
文件数据库=新文件(数据库路径);
如果(db.exists())返回真;
文件目录 = 新文件 (db.getParent());
如果(!dir.exists()){
目录.mkdirs();
}
返回假;
}
将数据库从assets复制到1处获取的路径指定的位置。
作为 4 的一部分,我获取 Assets 文件,检查前 16 个字节以查看它是否是有效的 SQLiteDatabase(必须是“SQLite format 3\u0000”)。
然后继续将数据库从 Assets 复制到数据库文件。
关于android - Assets 文件夹中的 SQLite 数据库在 Android Pie 中不起作用,即 API 28,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53517920/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!