Продолжайте получать NullPointerExceptions при попытке вызвать getWritableDatabase () - PullRequest
6 голосов
/ 16 августа 2010

Я новичок в платформе Android и не могу пройти первую базу с SQLite.

Я пытаюсь создать очень простое приложение, которое имеет окно поиска EditText, которое, когда ключнажатие выполняет поиск слов% word% в базе данных SQLite для текста, введенного в поле EditText, и отображает результаты в ListView.

NB приведенный ниже код включает отладочный и закомментированный код, извините, у меня нетеще не приступили к его очистке.

Активация

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 обработанаby 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.Мне удалось отследить ошибку в методе onCreate OpenHelper и "db.beginTransaction ();"линия.

Чего мне не хватает?

Ответы [ 2 ]

8 голосов
/ 16 августа 2010

На самом деле вам не нужно начинать транзакцию с помощью метода onCreate помощника. Попробуйте удалить все из метода, кроме db.execSQL(CREATE_TABLE_FEEDS);

Обновление : я смог повторить проблему.

Переместить инициализацию поля fishDb в метод действия onCreate() после того, как эта ошибка исчезнет. Похоже, что не стоит начинать инициализацию db до вызова onCreate.

Так что вместо

fishDB fishDb = new fishDB(getApplicationContext());

сделать

fishDB fishDb;

onCreate(){
  super.onCreate();
  fishDb = new fishDB(getApplicationContext());
  .... //init listener, query db etc..
}
2 голосов
/ 16 августа 2010

Следующий код получен из исходного учебника по 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 () и, возможно, открыть () в onResume (), закрыть () в 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» для первичного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...