HTC Desire HD 的 Sqlite 问题 [英] Sqlite issues with HTC Desire HD

查看:22
本文介绍了HTC Desire HD 的 Sqlite 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我收到了很多关于 HTC Desire 系列的抱怨,它在调用 sql 语句时失败.我收到了来自用户的报告,其中包含包含以下内容的日志快照.

Recently I have been getting a lot of complaints about the HTC Desire series and it failing while invoking sql statements. I have received reports from users with log snapshots that contain the following.

I/Database( 2348): sqlite returned: error code = 8, msg = statement aborts at 1: [pragma journal_mode = WAL;] 
E/Database( 2348): sqlite3_exec to set journal_mode of /data/data/my.app.package/files/localized_db_en_uk-1.sqlite to WAL failed

接下来是我的应用程序基本上着火了,因为打开数据库的调用会导致严重的运行时错误,表现为游标保持打开状态.此时不应该有游标,因为我们正在尝试打开它.

followed by my app basically burning in flames because the call to open the database results in a serious runtime error that manifests itself as the cursor being left open. There shouldn't be a cursor at this point as we are trying to open it.

这只发生在 HTC Desire HD 和 Z 上.我的代码基本上做了以下事情(做了一点改动以隔离问题区域).

This only occurs with the HTC Desire HD and Z. My code basically does the following (changed a little to isolate the problem area).

SQLiteDatabase db;
String dbName;

public SQLiteDatabase loadDb(Context context) throws IOException{
   //Close any old db handle
   if (db != null && db.isOpen()) {
      db.close();
   } 
  // The name of the database to use from the bundled assets.
  String dbAsset = "/asset_dir/"+dbName+".sqlite";
  InputStream myInput = context.getAssets().open(dbAsset, Context.MODE_PRIVATE);

  // Create a file in the app's file directory since sqlite requires a path
  // Not ideal but we will copy the file out of our bundled assets and open it
  // it in another location.
  FileOutputStream myOutput = context.openFileOutput(dbName, Context.MODE_PRIVATE);

  byte[] buffer = new byte[1024];
  int length;
  while ((length = myInput.read(buffer)) > 0) {
      myOutput.write(buffer, 0, length);
  }

  // Close the streams
  myOutput.flush();
  // Guarantee Write!
  myOutput.getFD().sync();
  myOutput.close();
  myInput.close();
  // Not grab the newly written file
  File fileObj = context.getFileStreamPath(dbName);
  // and open the database
  return db = SQLiteDatabase.openDatabase(fileObj.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}

遗憾的是,这款手机仅在英国有售,我的库存中没有.我只从 HTC Desire 系列中得到这种类型的报告.我不知道发生了什么变化,因为这段代码一直工作没有任何问题.有什么我遗漏的吗?

Sadly this phone is only available in the UK and I don't have one in my inventory. I am only getting reports of this type from the HTC Desire series. I don't know what changed as this code has been working without any problem. Is there something I am missing?

推荐答案

简短回答:尝试删除 SQLiteDatabase.OPEN_READONLY.

Short answer: try removing SQLiteDatabase.OPEN_READONLY.

更长的答案:

WAL"是预写日志,据我所知,这是 SQLite 中相对较新的功能.WAL 上的 SQLite 文档说不可能打开只读 WAL 数据库."现在,这似乎更适用于只读媒体,但它可能适用于 OPEN_READONLY.

The "WAL" is the write-ahead log, a relatively new feature in SQLite as I understand it. The SQLite docs on WAL say "It is not possible to open read-only WAL databases." Now, that appears to be more in the context of read-only media, but it might hold true for OPEN_READONLY.

如果这有帮助,我会感到有些惊讶,因为它假定:

I'd be somewhat surprised if this helps, as it presumes that:

  • WAL 未在标准 Android 中使用
  • HTC 在这两款设备中启用了 WAL
  • 您的环境的一些特殊情况(例如,您从资产中提取的二进制数据库)导致了这个问题,其中普通的只读数据库仍然可以正常工作,因为我无法想象这些设备会通过兼容性测试损坏的只读数据库支持

但是,我认为至少值得一试.

But, I would think it is at least worth a shot.

您还可以考虑从打包二进制数据库切换到打包 SQL 语句以构建/填充数据库并执行它们.虽然这会更慢(如果您不使用事务会更慢),但它可能不太容易出现特定于数据库文件的问题.

You might also consider switching from packaging the binary database to packaging the SQL statements to build/populate the database and executing them. While this will be slower (much slower if you don't use transactions), it might be less prone to database file-specific issues.

这篇关于HTC Desire HD 的 Sqlite 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆