Android .getWritableDatabase() NullPointerException

mirisbowring

Bekanntes Mitglied
Hi,

ich habe eine App, in der ich Notizen eintragen und in die Datenbank speichern möchte. allerdings schmeißt das Programm immer eine NullPointerException bei dbHelper.getWritabeleDatabase()...
Was ist mein Fehler?

dbHelper:
Java:
package com.example.arthurferdinand.newtz;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MySQLiteHelper extends SQLiteOpenHelper{

    //Name der Datenbank
    private static final String DATABASE_Name = "VERTRETUNG.db";
    //Datenbankversion
    private static final int DATABASE_VERSION = 1;

    //Datenbank wird erstellt
    public MySQLiteHelper(Context context) {
        super(context, DATABASE_Name, null, DATABASE_VERSION);
    }
    
    private static final String TABLE_CREATE_NOTIZEN = ""
            + "CREATE TABLE " + Ugv.TABLE_NOTIZEN + "("
            + Ugv.TABLE_NOTIZEN_ID + " INTEGER primary key autoincrement,"
            + Ugv.TABLE_NOTIZEN_TITLE + " VARCHAR(500),"
            + Ugv.TABLE_NOTIZEN_NOTIZ + " TEXT)";

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(TABLE_CREATE_NOTIZEN);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        //alte Datenbank löschen, wenn vorhanden (alle Daten werden gelöscht)
        database.execSQL("DROP TABLE IF EXISTS" + Ugv.TABLE_NOTIZEN);

        //Tabellen erneut erstellen
        onCreate(database);
    }
}

Die Commands Klasse:
Java:
package com.example.arthurferdinand.newtz;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;

public class Commands {
    private MySQLiteHelper dbHelper;
    Context c1;

    public Commands(Context context){
        c1 = context;
        dbHelper = new MySQLiteHelper(c1);
    }

    public int InsertNote(Ugv ugv){
        //DB Verbindung wird geöffnet
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        //Werte verwaltung
        ContentValues values = new ContentValues();
        values.put(ugv.TABLE_NOTIZEN_TITLE, ugv.notizTitel);
        values.put(ugv.TABLE_NOTIZEN_NOTIZ, ugv.NotizInhalt);

        //Insert Row
        long insert = db.insert(ugv.TABLE_NOTIZEN, null, values);
        db.close();
        Toast.makeText(null, "New Student Insert", Toast.LENGTH_SHORT).show();
        return (int) insert;
    }
}

In der Klasse Ugv werden Variablen zwischengespeichert...
 

buggy84

Bekanntes Mitglied
Könnte es daran liegen, dass ich keine Methode sehe, die
Code:
.getWritableDatabase();
heisst? *kopfkratz*

Wäre gut, wenn Du die Exception mitpostest.

edit: ich revidiere meine Meinung oben. Nachdem ich mir die Docs nochmal angeshen habe, abe ich die Methode doch gefunden. Es ist eben irgendwie doch Freitag...

Ich tippe auf eine nicht-existente Datenbank VERTRETUNG.db, wobei cih auch immer wieder betonen möchte, dass im Constructor keine Objekte zu erstellen sind. Das ist bad practice.
 
Zuletzt bearbeitet:

mirisbowring

Bekanntes Mitglied
Dass die Datenbank nicht existiert habe ich auch bereits vermutet.
Allerdings sollte die doch erstellt werden, wenn ich die Klasse aufrufe oder?

Du sagtest ja, dass ich im Constructor keine Objekte erstellen soll.
wäre dann sinnvoller, wenn ich den Constructor leer lasse und stattdessen eine Schleife einbaue, die Testet, ob die Datenbank existiert oder?
 

buggy84

Bekanntes Mitglied
Also habe ich weiter geschaut.
Fehler könnte hier liegen:

Code:
private static final String TABLE_CREATE_NOTIZEN = ""
            + "CREATE TABLE " + Ugv.TABLE_NOTIZEN + "("
            + Ugv.TABLE_NOTIZEN_ID + " INTEGER primary key autoincrement,"
            + Ugv.TABLE_NOTIZEN_TITLE + " VARCHAR(500),"
            + Ugv.TABLE_NOTIZEN_NOTIZ + " TEXT)";

Du hast Copy&Paste gemacht, oder? Das ist okay, aber vergleiche mal dieses hier

Code:
String CREATE_BOOK_TABLE = "CREATE TABLE books ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"title TEXT, "+
"author TEXT )";

mit deinem.

Ich frage mich außerdem, wo Ugv herkommt. Und warum es einmal mit Capital Letter geschrieben ist und das andere Mal nicht...

Nochmal: Wenn Du die Exception posten würdest, wäre das Rätselraten einfacher.

Zu Deiner Constructor-Frage: Ja, kann man so machen.

Ich lege Dir außerdem dieses Tutorial nahe:
http://hmkcode.com/android-simple-sqlite-database-tutorial/
 
Zuletzt bearbeitet:

mirisbowring

Bekanntes Mitglied
Hier erstmal die Fehlermeldung :)
Code:
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime: FATAL EXCEPTION: main
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime: java.lang.NullPointerException
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at com.example.arthurferdinand.newtz.Commands.InsertNote(Commands.java:22)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at com.example.arthurferdinand.newtz.MainActivity.insertNote(MainActivity.java:229)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at com.example.arthurferdinand.newtz.Add_Note.onClick(Add_Note.java:41)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.view.View.performClick(View.java:4107)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:17160)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:615)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:92)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:155)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5536)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:511)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)
12-06 12:37:31.977 4133-4133/com.example.arthurferdinand.newtz E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

Die Zeile 22 in Commands ist die .getWritableDatabase() Sache...
Die anderen beiden klassen werden angezeigt, da diese Methode dort aufgerufen wird.

Ich habe den Code nicht kopiert (ich arbeite viel mit DerbyDB und habe das selbe prinzip mit dem Varchar angwandt) Ich habe Varcher einmal zu Text gemacht, im Falle das SQlite nicht damit zurecht kommt. Hat allerdings nichts verändert.

Das Tutotial werde ich mir einmal anschauen :)
 

buggy84

Bekanntes Mitglied
Hast Du das mal anstatt deinem Code benutzt?
Code:
String CREATE_BOOK_TABLE = "CREATE TABLE books ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"title TEXT, "+
"author TEXT )";

Hast Du Ugv genau dieser Stelle mal auf null überprüft?
 

buggy84

Bekanntes Mitglied
Hast du auf null überprüft? Mal den Debugger angeworfen? Wenn dein ugv irgendwo existiert, kann es trotzdem an dieser Stelle null sein.
 

mirisbowring

Bekanntes Mitglied
Also ich habe jetzt nocheinmal eine ganze Menge versuche und iden gehabt, das Probelm aber dennoch nicht lösen können...

Die String in Ugv sind alle NICHT null,
soweit ich das mit dem Debugger anchvollziehen konnte, ist die datenbank auch erstellt worden, da in der Methode public MySQLiteHelper keine fehlermeldung ausgegeben wurde.

Er stoppt wie gesagt erst bei dem getWritable... :/


Ich habe echt keine idee mehr, woher die nullpointerexception kommt
 

Joose

Top Contributor
Du verwendest im MySqlLiteHelper einen Context, dieser wird in der Klasse Commands übergeben.
Was ist das für ein Objekt? Kann es sein das diese Objekt null ist? Ist der Context richtig initalisiert?

(Habe mir den Source der Klassen ContextWrapper und SqlLiteOpenHelper etwas angeschaut. Deswegen würde ich am ehersten auf diesen Context tippen)
 

mirisbowring

Bekanntes Mitglied
Was das angeht, habe ich mich an ein Tutorial gehalten.
Ich rufe die Helper klasse in meiner MainActivity auf mit (this), womit der dann in die public methode der Helper klasse springt.

Bisher habe ich eben einen Fehler dort ausgeschlossen, weil das Super ja einwandfrei funktioniert hat :)
 

Joose

Top Contributor
Wie gesagt hab eben nur ein bisserl den SourceCode verfolgt was aber nicht immer viel aussagen kann (Aufrufe per Reflection, Ableitungen etc.)

Nur weil keine Exception fliegt muss es noch lange nicht passen. Beim setzen werden die Parameter nicht auf null überprüft.
 

mirisbowring

Bekanntes Mitglied
Das wird mir beim Debugger als context angezeigt (ziemlich viel null oder?)

Code:
context = {MainActivity@830021050312}
swipeView = null
fragment = null
planurl = {String@830020079384} "https://dl.dropboxusercontent.com/s/j6p9lv7f4uapgp9/GPU014.TXT"
_Note_ID = 0
mDelegate = null
mMediaController = null
mFragments = {FragmentController@830021051056}
mHandler = {FragmentActivity$1@830021050840} "Handler (android.support.v4.app.FragmentActivity$1) {411c21d8}"
mCreated = false
mOptionsMenuInvalidated = false
mReallyStopped = false
mRequestedPermissionsFromFragment = false
mResumed = false
mRetaining = false
mStopped = false
mActionBar = null
mActivityInfo = null
mAllLoaderManagers = null
mApplication = null
releaseMemoryRunnable = {Activity$1@830021050824}
mWindowManager = null
mWindow = null
mComponent = null
mUiThread = null
mCurrentConfig = null
mDecor = null
mToken = null
mDefaultKeySsb = null
mEmbeddedID = null
mTitle = null
mSearchManager = null
mFragments = {FragmentManagerImpl@830021050600} "FragmentManager{411c20e8 in null}}"
mHandler = {Handler@830021050792} "Handler (android.os.Handler) {411c21a8}"
mResultData = null
mInstanceTracker = {StrictMode$InstanceTracker@830021050736}
mInstrumentation = null
mIntent = null
mLastNonConfigurationInstances = null
mLoaderManager = null
mParent = null
mMainThread = null
mManagedCursors = {ArrayList@830021050712}  size = 0
mManagedDialogs = null
mMenuInflater = null
mLoadersStarted = false
mResultCode = 0
mIdent = 0
mResumed = false
mFinished = false
mStartedActivity = false
mStopped = false
mTemporaryPause = false
mEnableDefaultActionBarUp = false
mTitleColor = 0
mTitleReady = false
mDefaultKeyMode = 0
mConfigChangeFlags = 0
mVisibleFromClient = true
mVisibleFromServer = false
mCheckedForLoaderManager = false
mWindowAdded = false
mChangingConfigurations = false
mCalled = false
mBase = null
mInflater = null
mTheme = null
mThemeResource = 0
mThemeResourceFix = 0
mBase = null
 

buggy84

Bekanntes Mitglied
Ok, dein Problem ist, dass Du in Add_Note eine Instanz von MainActivity erstellst. Das darfst Du nicht machen. Ich habe das jetzt quick and dirty so gemacht:
in Ugv:

Code:
public static MainActivity ctx;

in onCreate von MainActivity:
Code:
Ugv.ctx=this;

in Add_Note onClick

Code:
//MainActivity ma = new MainActivity();
Ugv.ctx.insertNote();

und dann noch in Commands den Toast berichtigt

Code:
Toast.makeText(c1, "New Student Insert", Toast.LENGTH_SHORT).show();

tadaaaa :) wie gesagt, quick&dirty, aber jetzt siehst Du wo der Fehler liegt.
 

Ähnliche Java Themen

Neue Themen


Oben