【发布时间】:2014-01-08 17:07:15
【问题描述】:
我正在使用 SQLiteAssetHelper 库来处理我的 App DB 操作,它几乎适用于我测试过的所有手机。但是,一些使用 Android 2.3.3 - 2.3.7 的用户在调用打开数据库时报告崩溃。我怀疑这是由于第一次从资产文件夹复制数据库时发生的一些问题(例如内部存储空间不足)。
助手类:
public class DbHelper extends SQLiteAssetHelper {
final static String DB_NAME="db";
static final int DB_VERSION = 1307181213;
final Context context;
public DbHelper(Context c) {
super(c, DB_NAME, null, DB_VERSION);
this.context = c;
setForcedUpgradeVersion(DB_VERSION);
}
}
处理程序类(如果无法打开数据库,我将计数器设置为 10 秒后超时) :
public class DbHandlerDao {
private SQLiteDatabase database;
private DbHelper dbHelper;
public DbHandlerDao(Context context) {
dbHelper = new DbHelper(context);
}
public void open() throws SQLException {
boolean opened = false;
int timeout = 0;
while (!opened && timeout < 10000) {
try {
database = dbHelper.getReadableDatabase();
opened = true;
}
catch (IllegalStateException e) {
timeout += 500;
try {
Thread.sleep(500);
} catch (Exception e2) {
}
}
}
}
public void close() {
dbHelper.close();
}
调用类:
private class DbAsyncTask extends AsyncTask<Long, Void, Void> {
//...
@Override
protected Void doInBackground(Long... params) {
dataHandler.open();
例外:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.NullPointerException
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getWritableDatabase(SQLiteAssetHelper.java:180)
at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:257)
at com.example.DbHandlerDao.open(DbHandlerDao.java:25)
at com.example.SearchActivity$DbAsyncTask.doInBackground(SearchActivity.java:244)
at com.example.SearchActivity$DbAsyncTask.doInBackground(SearchActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
【问题讨论】:
-
我在运行 Android 4.3 和 4.4 的几台设备上遇到了似乎相同的错误。奇怪的是,我无法始终如一地重现它。
-
我会将它作为 github 项目本身的问题发布,因为它几乎可以保证是库的问题 - 标准 SQLiteOpenHelper 没有这个问题。似乎其他人也有这个问题:github.com/jgilfelt/android-sqlite-asset-helper/issues/23
-
谢谢,好主意。但经过更多调查后,我意识到这是我自己的错误。长话短说,我正在从一个活动的
onCreate方法调用的AsyncTask中复制一个数据库,然后尝试使用同一个数据库填充ListView。事实证明,只有当我很幸运并且后台任务在ListView需要数据库之前完成时才有效! -
只是快速说明没有基于计时器的循环,用户无法取消。您最终可能会锁定 ui 线程,并且您的应用将显示无响应。
-
danny117,我在后台运行的 asyncTask 中调用 dataHandler.open()