SQLiteAssetHelper仅在某些设备上出现NullPointerException

我正在使用SQLiteAssetHelper库来处理我的应用程序数据库操作,它几乎适用于我testing过的每个手机。 然而,一些用户与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秒后,如果db无法打开):

 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) 

Solutions Collecting From Web of "SQLiteAssetHelper仅在某些设备上出现NullPointerException"

用户可能已经清除了存储空间,或者没有SD卡?

可能是什么零星的碰撞正在发生。

** 你是否实现了oncreate和onupgrade方法?

我使用开放的帮手。 所以我从来没有麻烦打开数据库。

  public class RidesDatabaseHandler extends SQLiteOpenHelper { 

  // Creating Tables @Override public void onCreate(SQLiteDatabase db) { String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_RIDES + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_DESCRIPTION + " TEXT," + KEY_BOUNDS_NELAT + " TEXT," + KEY_BOUNDS_NELONG + " TEXT," + KEY_BOUNDS_SWLAT + " TEXT," + KEY_BOUNDS_SWLONG + " TEXT," + KEY_RESRAWID + " TEXT," + KEY_RESDRAWABLEID + " TEXT," + KEY_PATH + " TEXT," + " CONSTRAINT UNQ_" + KEY_PATH + " UNIQUE (" + KEY_PATH + ") ON CONFLICT ABORT)"; // VERSION 43 ADDS THE KEY_DATE_UPDATE COLUMN CREATE_CONTACTS_TABLE += " , " + KEY_DATE_UPDATE + " INTEGER DEFAULT 0"; db.execSQL(CREATE_CONTACTS_TABLE); } // Upgrading database @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { int upgradeTo = oldVersion + 1; while (upgradeTo <= newVersion) { switch (upgradeTo) { // update old resrawid's to constants // this was caused when I saved R values in the database // and then later realized they would change. // the old resrawid is changed to a constant. case 42: ContentValues values; @SuppressWarnings("unused") // used for debugging so I can see the value of the update. int res; int rs; rs = 2130968576; values = new ContentValues(); values.put( KEY_RESRAWID, com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_DRAGON); res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?", new String[] { String.valueOf(rs) }); rs = 2130968577; values = new ContentValues(); values.put( KEY_RESRAWID, com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_M119); res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?", new String[] { String.valueOf(rs) }); rs = 2130968578; values = new ContentValues(); values.put( KEY_RESRAWID, com.gosylvester.bestrides.ImageTextListViewActivity.SAMPLE_MEDINA); res = db.update(TABLE_RIDES, values, KEY_RESRAWID + " = ?", new String[] { String.valueOf(rs) }); break; case 43: // new column added for last_viewed. db.execSQL(VERSION_43_ALTER); break; case 44: // new index on KEY_DATE_UPDATE DESC db.execSQL(VERSION_44_CREATE_INDEX); } upgradeTo++; } 

祝你好运

这个问题没有被接受的答案,即使OP表示在评论中已经解决了。 所以这里是答案:

不要尝试使用从方法调用的AsyncTask (例如onCreate )来复制数据库,然后尝试使用同一方法从数据库中填充数据。 如果在ListView需要数据的时候AsyncTask还没有完成,那么将引发一个NullPointerExceptionexception。

而是从AsyncTaskonPostExecute方法填充ListView 。 这将确保数据库已经完成复制。