尝试调用getWritableDatabase()时继续获取NullPointerExceptions

时间:2010-08-15 21:52:00

标签: android sqlite

我是Android框架的新手,我无法通过SQLite获得第一个基础。

我正在尝试构建一个非常简单的应用程序,它有一个EditText搜索框,当按下某个键时,会在SQLite数据库上执行Like%word%搜索,以获取在EditText框中输入的文本,并显示得到一个ListView。

N.B。下面的代码包括调试和注释代码,对不起,我还没有完成清理它。

激活是

public class sustainable_fish extends Activity {

private String keycodeToAscii(int arg2){

    String retvar = "";

    switch(arg2){
    case KeyEvent.KEYCODE_A: retvar = "a";break;
    case KeyEvent.KEYCODE_B: retvar = "b";break;

剪断,但你明白了。

    case KeyEvent.KEYCODE_RIGHT_BRACKET: retvar = ")";break;
    default: retvar = ""; break;
    };
    return retvar;

}



 Context that = getApplicationContext();
 fishDB dh = new fishDB(getApplicationContext());


private OnKeyListener search = new OnKeyListener() {

    public boolean onKey(View arg0, int arg1, KeyEvent arg2) {


        @SuppressWarnings("unused")
        Cursor cur = null;
        String searchData;
        EditText myEditText = (EditText) findViewById(R.id.fish_search);
        CharSequence edit_text_value = myEditText.getText();
        searchData = edit_text_value.toString();
        searchData = searchData + keycodeToAscii(arg2.getKeyCode() );
        Log.d("onKey", "searchData = "+searchData);
        /*
        Commented out because as the database doesn't work, so theirs no point just yet searching.

        cur = fish.search(searchData);
        if (cur != null)
        {
            String[] displayFields = new String[] {cur.getString(2),
                    cur.getString(1)};

            int[] displayViews = new int[] { R.id.fish_rank,
                    R.id.fish_name};

            SimpleCursorAdapter adapter = new SimpleCursorAdapter(that, 
                    R.layout.text_list, cur, 
                    displayFields, displayViews);

            ListView myList=(ListView)findViewById(android.R.id.list);

            myList.setAdapter(adapter);
        } 
        */

        return false;
    }

};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

   setContentView(R.layout.main);
   EditText searchBar = (EditText) findViewById(R.id.fish_search);
   searchBar.setOnKeyListener(search); 

}

}

SQLite数据库由fishDB处理

  public class fishDB {

 public static final String DATABASE_NAME = "fish.db3";
 public static final int DATABASE_VERSION = 1;
 private SQLiteDatabase database;
 private Context myContext;
 private static boolean booFirstrun = false;

 fishDB(Context inContext){
     myContext = inContext;
     OpenHelper helper = new OpenHelper(myContext);
     Log.w("fishDB", "Called OpenHelper");

             // Here be the problem...

     database = helper.getWritableDatabase();

 }

 public boolean firstRun(){
    return booFirstrun;
 }


   private static class OpenHelper extends SQLiteOpenHelper {

       private static final String CREATE_TABLE_FEEDS = "create table feeds (feed_id integer primary key autoincrement, "
           + "title text not null, url text not null);";

          OpenHelper(Context context) {
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
             Log.w("OpenHelper", "Called superconstructor");
            }

          @Override
          public void onCreate(SQLiteDatabase db) {
              try {
              Log.w("OpenHelper", "in onCreate");
              booFirstrun = true;
              Log.w("OpenHelper", "set booFirstrun");
              db.beginTransaction();
              Log.w("OpenHelper", "db.beginTransaction");
              try {
                  // Create tables and test data
                  db.execSQL(CREATE_TABLE_FEEDS);
                  Log.w("OpenHelper", "execSQL");
                  db.setTransactionSuccessful();
                  Log.w("OpenHelper", "setTransactionSuccessful");
              } catch (SQLException e) {
                  Log.e("Error creating tables and debug data", e.toString());
                  throw e;
              } finally {
                  db.endTransaction();
              }
              } catch (Exception e) {
                  Log.e("OpenHelper", e.toString() );
              } finally {
              Log.w("OpenHelper", "out of onCreate");
              }
          }

          @Override
          public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             Log.w("OpenHelper", "Upgrading database, this will drop tables and recreate.");
             onCreate(db);
          }
       } 
 }

现在每次“database = helper.getWritableDatabase();”被称为应用程序崩溃与NullPointerException。我设法将错误跟踪到OpenHelper的onCreate方法和“db.beginTransaction();”线。

我错过了什么?

2 个答案:

答案 0 :(得分:8)

实际上,您不需要在帮助程序的onCreate方法上启动事务。尝试从db.execSQL(CREATE_TABLE_FEEDS);

以外的方法中删除所有内容

更新:我能够重复此问题。

在该错误消失后,将fishDb字段初始化移至onCreate()活动方法。看起来在调用onCreate之前启动数据库初始化并不是一个好主意。

所以而不是

fishDB fishDb = new fishDB(getApplicationContext());

DO

fishDB fishDb;

onCreate(){
  super.onCreate();
  fishDb = new fishDB(getApplicationContext());
  .... //init listener, query db etc..
}

答案 1 :(得分:2)

以下代码源自最初的Android NotePad教程:

public class FishDb {

private static final String TAG = "FishDb";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

private static final String CREATE_TABLE_FEEDS = "create table feeds (_id integer primary key autoincrement, "
       + "title text not null, url text not null);";

public static final String DATABASE_NAME = "fish.db3";
public static final String DATABASE_TABLE = "feeds";
private static final int DATABASE_VERSION = 1;

private final Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(CREATE_TABLE_FEEDS);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS feeds");
        onCreate(db);
    }
}

public DbAdapter(Context ctx) {
    this.mCtx = ctx;
}

public DbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}

// ... The helper methods
}

您可以在onCreate()中实例化实例化,并在onPesume()上打开on(),在onPause()上关闭():

private FishDb mDbHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mDbHelper = new FishDb(this);
}

@Override
public void onResume() {
    super.onResume();
    try{
        mDbHelper.open();
    } catch(Exception e){
        Log.e("onResume", e.toString());
    }
}

@Override
public void onPause() {
    super.onPause();
    try{
        mDbHelper.close();
    }  catch(Exception e){
        Log.e("onPause", e.toString());
    }
}

希望有所帮助。

编辑:使用“_id”而不是“feed_id”作为主键。