Immer NullPointerExceptions, wenn Sie versuchen, um call getWritableDatabase()
Ich bin neu in der Android-framework, und ich kann nicht vorbei an der ersten base mit SQLite.
Ich versuche zu bauen eine sehr einfache Anwendung, die hat ein EditText Feld Suche, die, wenn eine Taste gedrückt wird, führt eine Wie %Wort% Suche auf eine SQLite-Datenbank für die Eingabe von text in die EditText-box, und zeigt die Ergebnisse in einer ListView.
N. B. den folgenden code enthalten debugging und kommentierten code, sorry, ich habe nicht rund um die Reinigung noch.
Aktivieren ist
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;
geschnippelt, aber Sie bekommen die Idee.
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);
}
}
Die SQLite-Datenbank erfolgt durch 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);
}
}
}
Nun jedes mal "Datenbank = helper.getWritableDatabase();" aufgerufen wird, stürzt die app mit einer NullPointerException. Ich habe es geschafft auf die Spur, die Fehler in der onCreate-Methode der OpenHelper und die "db.beginTransaction();" Zeile.
Was bin ich?
- Auch für die Referenz (mine, wenn niemand elses)
db.endTransaction();
bewirkt, dass die onCreate-zu scheitern (und fehl) verursacht einen runtime error inOpenHelper helper = new OpenHelper(myContext);
und nicht schreiben alle Tabellen der Datenbank (und damit verursacht eine zusätzliche SQLException auf den nächsten Anruf). Hoffe, dass dies halt etwas anderes verschwenden ein Tag, tracking es nach unten (oder nur mich das nächste mal Schreibe ich eine Datenbank-Klasse)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eigentlich nicht brauchen, starten Sie die Transaktion bei der onCreate-Methode des Helfers. Entfernen Sie alles von der Methode, außer
db.execSQL(CREATE_TABLE_FEEDS);
Update: ich konnte das problem reproduzieren.
Bewegen fishDb Feld Initialisierung der
onCreate()
Methode Aktivitäten nach, dass der Fehler verschwindet. Wie es aussieht ist es keine gute Idee zu Beginn der db-Initialisierung vor der onCreate aufgerufen.Also statt
tun
Folgende code ist abgeleitet von der ursprünglichen Android-Notizblock tutorial:
Würden Sie instanziieren Sie in Ihren Aktivitäten onCreate() und eventuell open() in onResume(), close() auf onPause():
Hoffe, das hilft.
BEARBEITEN: Nutzung "_id" statt "feed_id" für Primärschlüssel.