SQLiteOpenHelper.getWritableDatabase() throws NullPointerExc



这是我在DatabaseHandler类中使用的方法集,该类从OrmLiteSqliteOpenHelper:扩展而来

@Override
        public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) 
        {
         try
         {  
            TableUtils.createTable(connectionSource, Category.class);
            TableUtils.createTable(connectionSource, Level.class);
            DataParsing a = new DataParsing();
            a.wrapCategories();
            Log.i(DatabaseHandler.class.getName(), "created new entries in onCreate: " );
         }
         catch (SQLException e){
             Log.e(TAG, "error creating DB " + DATABASE_NAME);
             throw new RuntimeException(e);
         } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
    // Upgrading database
      @Override
       public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVer, int newVer)
      {
           try
            {          
               TableUtils.dropTable(connectionSource, Category.class, true);
               TableUtils.dropTable(connectionSource, Level.class, true);
               onCreate(db, connectionSource);
            }
           catch (SQLException e){
               Log.e(TAG,"error upgrading db "+DATABASE_NAME+"from ver "+oldVer);
               throw new RuntimeException(e);
           }
       }

      public Dao<Category, Integer> getCategoryDao() throws SQLException 
        {
            if (simpleCategoryDao == null) {
                simpleCategoryDao = getDao(Category.class);
            }
            return simpleCategoryDao;
        }
      public Dao<Level, Integer> getLevelDao() throws SQLException 
        {
            if (simpleLevelDao == null) {
                simpleLevelDao = getDao(Level.class);
            }
            return simpleLevelDao;
        }

当我运行我的应用程序时,我会收到这样的消息

08-03 16:44:08.619: V/droidDatabaseConnection(12196): AndroidDatabaseConnection@405182b0: compiled statement got AndroidCompiledStatement@40578b10: CREATE TABLE `categories` (`title` VARCHAR , `id` INTEGER , PRIMARY KEY (`id`) ) 
08-03 16:44:08.619: V/ndroidCompiledStatement(12196): compiled statement runExecute changed 1 rows: CREATE TABLE `categories` (`title` VARCHAR , `id` INTEGER , PRIMARY KEY (`id`) ) 
08-03 16:44:08.629: V/droidDatabaseConnection(12196): AndroidDatabaseConnection@405182b0: compiled statement got AndroidCompiledStatement@405f0f50: CREATE TABLE `levels` (`title` VARCHAR , `id` INTEGER , PRIMARY KEY (`id`) ) 
08-03 16:44:08.629: V/ndroidCompiledStatement(12196): compiled statement runExecute changed 1 rows: CREATE TABLE `levels` (`title` VARCHAR , `id` INTEGER , PRIMARY KEY (`id`) ) 

据我所知,数据库已成功创建。然后我想在那里放一个对象列表,方法是:

public void saveContacts(List<Category> contacts) throws SQLException
    {
        OrmLiteSqliteOpenHelper dbHelper= DatabaseHandler.getInstance(_context);
        String res = Boolean.toString(dbHelper.isOpen());
        Log.i(" 123 ",res);
        dbHelper.getWritableDatabase();
        Dao<Category, Integer> daoContact=dbHelper.getDao(Category.class);
        QueryBuilder<Category, Integer> queryBuilder = daoContact.queryBuilder();
        daoContact.queryRaw("insert into categories values (hello, 1)");
        Log.i("dao",queryBuilder.selectColumns("title").prepare().toString());
        for (Category contact : contacts) {
            Log.i("dao",contact.toString());
            HelperFactory.GetHelper().getCategoryDao().createIfNotExists(contact);
        }
      }

并且在行dbHelper.getWritableDatabase()上;我得到

08-03 16:44:29.199: E/AndroidRuntime(12196): FATAL EXCEPTION: main
08-03 16:44:29.199: E/AndroidRuntime(12196): java.lang.NullPointerException
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at com.assignmentexpert.LoginActivity.saveContacts(LoginActivity.java:268)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at com.assignmentexpert.LoginActivity$4.onClick(LoginActivity.java:132)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.view.View.performClick(View.java:2485)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.view.View$PerformClick.run(View.java:9080)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.os.Handler.handleCallback(Handler.java:587)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.os.Looper.loop(Looper.java:123)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at android.app.ActivityThread.main(ActivityThread.java:3687)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at java.lang.reflect.Method.invokeNative(Native Method)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at java.lang.reflect.Method.invoke(Method.java:507)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-03 16:44:29.199: E/AndroidRuntime(12196):    at dalvik.system.NativeStart.main(Native Method)

为什么会发生这种情况?

public void saveContacts(List<Category> contacts) throws SQLException
{
    OrmLiteSqliteOpenHelper dbHelper= DatabaseHandler.getInstance(_context);
    String res = Boolean.toString(dbHelper.isOpen());
    Log.i(" 123 ",res);
    dbHelper= this.getWritableDatabase(); <----- here change will may help you
    Dao<Category, Integer> daoContact=dbHelper.getDao(Category.class);
    QueryBuilder<Category, Integer> queryBuilder = daoContact.queryBuilder();
    daoContact.queryRaw("insert into categories values (hello, 1)");
    Log.i("dao",queryBuilder.selectColumns("title").prepare().toString());
    for (Category contact : contacts) {
        Log.i("dao",contact.toString());
        HelperFactory.GetHelper().getCategoryDao().createIfNotExists(contact);
    }
  }

通过将我的活动上下文传递给OrmLiteSqliteOpenHelper解决了问题。我使用这样的类在整个应用程序生命周期中维护对数据库的访问:

public class ApplicationMemory extends Application{
   @Override
   public void onCreate() {
       super.onCreate();
       HelperFactory.SetHelper(getApplicationContext());
   }
   @Override
   public void onTerminate() {
       HelperFactory.ReleaseHelper();
       super.onTerminate();
   }
}

 public class HelperFactory {
 private static DatabaseHandler databaseHelper;
   public static DatabaseHandler GetHelper(){
       return databaseHelper;
   }
public static void SetHelper(Context context){
       databaseHelper = OpenHelperManager.getHelper(context,DatabaseHandler.class);
   }
public static void ReleaseHelper(){
       OpenHelperManager.releaseHelper();
       databaseHelper = null;
   }
   }

其中DatabaseHandler-class,它是从OrmLiteSqliteOpenHelper扩展而来的,并在我的问题中进行了描述。

非常感谢Hardik Nadyapara。他帮了很多忙。

最新更新