使用游标时发生Java空指针异常

使用游标时发生Java空指针异常,java,android,nullpointerexception,android-cursor,Java,Android,Nullpointerexception,Android Cursor,我为什么这么问:我不想听起来粗鲁,但我非常绝望。我尝试了这些东西,你已经在几个问题中描述了大约8个小时,但是没有其他人的帮助,我无法理解。我理解NullPointerException理论和您的示例,但我不知道如何做得更好,尤其是与一个运行良好的示例相比。我只为数据库中的表修改了几个变量,我需要一些关于我的案例的解释。如果我能自己找到答案,我不会问。请帮我解决问题。 我试着学习Android编程。为了做到这一点,我使用了一个教程来解释如何创建SQLite数据库 虽然我和作者之一检查了我的代码,并

我为什么这么问:我不想听起来粗鲁,但我非常绝望。我尝试了这些东西,你已经在几个问题中描述了大约8个小时,但是没有其他人的帮助,我无法理解。我理解NullPointerException理论和您的示例,但我不知道如何做得更好,尤其是与一个运行良好的示例相比。我只为数据库中的表修改了几个变量,我需要一些关于我的案例的解释。如果我能自己找到答案,我不会问。请帮我解决问题。

我试着学习Android编程。为了做到这一点,我使用了一个教程来解释如何创建SQLite数据库

虽然我和作者之一检查了我的代码,并检查了关于这个错误的堆栈溢出,但我还并没有发现我的错误

当我测试我的应用程序时,我的日志中有以下内容:

    02-25 14:00:48.951 16343-16343/de.der_kalorienzaehler.kalorienzaehler D/AndroidRuntime: Shutting down VM
    02-25 14:00:49.007 16343-16343/de.der_kalorienzaehler.kalorienzaehler E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                                Process: de.der_kalorienzaehler.kalorienzaehler, PID: 16343
                                                                                                java.lang.RuntimeException: Unable to start activity ComponentInfo{de.der_kalorienzaehler.kalorienzaehler/de.der_kalorienzaehler.kalorienzaehler.zutat_bearbeiten}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor 
...                                                                                              
                                                                                                 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)' on a null object reference
                                                                                                    at de.der_kalorienzaehler.kalorienzaehler.DbZugriff.getAllGrundgeruestZutatenverwaltung(DbZugriff.java:92)
                                                                                                    at de.der_kalorienzaehler.kalorienzaehler.zutat_bearbeiten.listenEintraegeZeigen(zutat_bearbeiten.java:58)
                                                                                                    at de.der_kalorienzaehler.kalorienzaehler.zutat_bearbeiten.onCreate(zutat_bearbeiten.java:49)
我认为引起我所有问题的原因如下:
de.der_kalorienzaehler.kalorienzaehler.DbZugriff.getAllGrundgeruestZutatenverwaltung(DbZugriff.java:92)

活动“zutat_bearbeiten”中的其他问题依赖于光标的值,因此无需更改。我试着初始化db,正如我班上其他名为“dbErzeugenUpdaten”的帖子所建议的那样。但当我尝试时,要么是一个无限循环,要么我无法初始化它,因为它已经存在了

所以我的问题是,为了避免NullPointerException,我必须写什么?也许我的问题的根源是错误的,所以我也向您展示了类“zutat_bearbeiten”,但是如果光标的问题得到解决,这个类应该是可以的

我期待着你的帮助

DbZugriff类:

package de.der_kalorienzaehler.kalorienzaehler;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.content.ContentValues;
import android.database.Cursor;
import java.util.ArrayList;
import java.util.List;
public class DbZugriff {

    private static final String LOG_TAG = DbZugriff.class.getSimpleName();

    private SQLiteDatabase database;
    private DbErzeugenUpdaten dbErzeugenUpdaten;

    //Für Suchanfragen
    private String[] columns = {
            DbErzeugenUpdaten.COLUMN_ID,
            DbErzeugenUpdaten.COLUMN_ZUTAT,
            DbErzeugenUpdaten.COLUMN_ANZAHL,
            DbErzeugenUpdaten.COLUMN_EINHEIT,
            DbErzeugenUpdaten.COLUMN_KCAL
    };

    //Context: Zugang zu Android Funktionen
    public DbZugriff(Context DbZugriff) {
        Log.d(LOG_TAG, "Unsere DataSource erzeugt jetzt den DbErzeugenUpdaten.");
        dbErzeugenUpdaten = new DbErzeugenUpdaten(DbZugriff);
    }

    public void open(){
        Log.d(LOG_TAG, "Eine Referenz auf die Datenbank wird angefragt");
        database = dbErzeugenUpdaten.getWritableDatabase();
        Log.d(LOG_TAG, "Datenbankreferenz erhalten. Pfad zur Datenbank" + database.getPath());
    }

    public void close(){
        dbErzeugenUpdaten.close();
        Log.d(LOG_TAG, "Datenbank mithilfe der Methode DbErzeugenUpdaten geschlossen");
    }

    //Einfügen von Daten in db
    public GrundgeruestZutatenverwaltung createGrundgeruestZutatenverwaltung(
            String zutat, double anzahl, String einheit, int kcal) {
        ContentValues daten_zutat = new ContentValues();
        daten_zutat.put(DbErzeugenUpdaten.COLUMN_ZUTAT, zutat);
        daten_zutat.put(DbErzeugenUpdaten.COLUMN_ANZAHL, anzahl);
        daten_zutat.put(DbErzeugenUpdaten.COLUMN_EINHEIT, einheit);
        daten_zutat.put(DbErzeugenUpdaten.COLUMN_KCAL, kcal);

        //nach id die Daten einfügen
        long idEinfuegen = database.insert(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, null, daten_zutat);

        Cursor cursor = database.query(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, columns,
                DbErzeugenUpdaten.COLUMN_ID + "=" + idEinfuegen, null, null, null, null);
        cursor.moveToFirst();
        GrundgeruestZutatenverwaltung datenCursor = cursorToGrundgeruestZutatenverwaltung(cursor);
        cursor.close();

        return datenCursor;
    }

    //Auslesen von Daten, aus Cursordaten werden Daten zur Weiterverwendung
    private GrundgeruestZutatenverwaltung cursorToGrundgeruestZutatenverwaltung(Cursor cursor){
        int idIndex = cursor.getColumnIndex(DbErzeugenUpdaten.COLUMN_ID);
        int idZutat = cursor.getColumnIndex(DbErzeugenUpdaten.COLUMN_ZUTAT);
        int idAnzahl = cursor.getColumnIndex(DbErzeugenUpdaten.COLUMN_ANZAHL);
        int idEinheit = cursor.getColumnIndex(DbErzeugenUpdaten.COLUMN_EINHEIT);
        int idKcal = cursor.getColumnIndex(DbErzeugenUpdaten.COLUMN_KCAL);

        long id = cursor.getLong(idIndex);
        String zutat = cursor.getString(idZutat);
        double anzahl = cursor.getDouble(idAnzahl);
        String einheit = cursor.getString(idEinheit);
        int kcal = cursor.getInt(idKcal);


        GrundgeruestZutatenverwaltung datenCursor = new GrundgeruestZutatenverwaltung
                (id, zutat, anzahl, einheit, kcal);
        return datenCursor;
    }

    //Auslesen aller Datensätze
    public List<GrundgeruestZutatenverwaltung> getAllGrundgeruestZutatenverwaltung(){
        List<GrundgeruestZutatenverwaltung> zutatenListe = new ArrayList<>();

        //Nullpointer Exception -> das ist einer der wichtigeren Probleme
        Cursor cursor = database.query(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, columns,
                null, null, null, null, null);

        cursor.moveToFirst();
        GrundgeruestZutatenverwaltung datenCursor;

        //Zeilenweise auslesen der Tabelle und werden zu umgewandelte Objekte, die in die zutatenListe kommen
        while (!cursor.isAfterLast()){
            datenCursor = cursorToGrundgeruestZutatenverwaltung(cursor);
            zutatenListe.add(datenCursor);
            Log.d(LOG_TAG, "ID:" + datenCursor.getId() + ", Inhalt:"
            + datenCursor.toString());
            cursor.moveToNext();
        }
        cursor.close();
        return zutatenListe;
    }


}
zutat_bearbeiten级:

//Tabelle wird erzeugt
package de.der_kalorienzaehler.kalorienzaehler;

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

public class DbErzeugenUpdaten extends SQLiteOpenHelper {
    //Methode getSimpleName gibt den Klassenname der Datei aus
    private static final String LOG_TAG =
            DbErzeugenUpdaten.class.getSimpleName();

    public static final String DB_NAME = "kcal_berechnen.db";
    public static final int DB_VERSION = 1;
    public static final String TABLE_ZUTATENLISTE = "zutatenliste";

    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_ZUTAT = "zutat";
    public static final String COLUMN_ANZAHL = "anzahl";
    public static final String COLUMN_EINHEIT = "einheit";
    public static final String COLUMN_KCAL = "kcal";

    public static final String SQL_CREATE =
            "CREATE TABLE " + TABLE_ZUTATENLISTE +
            "(" + COLUMN_ID  + " INTEGER PRIMARY KEY AUTOINCREMENT , " +
                COLUMN_ZUTAT  + " TEXT NOT NULL, " +
                COLUMN_ANZAHL  + " FLOAT NOT NULL, " +
                COLUMN_EINHEIT  + " TEXT NOT NULL, " +
                COLUMN_KCAL  + " INTEGER NOT NULL);";

    //Konstruktor, neue Instanz, wichtigste Daten für Erzeugung der db, db_info enthält Daten
    public DbErzeugenUpdaten (Context db_info){
        super(db_info, DB_NAME, null, DB_VERSION);
        // Log.d sendet eine Debug Log Nachricht
        Log.d(LOG_TAG, "Datenbank " + getDatabaseName() + " erzeugt");


    }

    //wird nur aufgerufen, wenn die Datenbank nicht existiert
    @Override
    public void onCreate(SQLiteDatabase db) {
        // muss initialisiert werden

        if (db != null){
            Log.d(LOG_TAG, "db ist nicht null");
        }else{
            Log.d(LOG_TAG, "db ist null");
        }
        Log.d(LOG_TAG, "DbErzeugenUpdaten OnCreate wird aufgerufen");
        try{
            Log.d(LOG_TAG, "Tablle wurde mithilfe" + SQL_CREATE + "angelegt");
            db.execSQL(SQL_CREATE);
        }catch(Exception ex){
            Log.e(LOG_TAG, "Fehler beim Anlegen der Tabelle" + ex.getMessage());
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
package de.der_kalorienzaehler.kalorienzaehler;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.List;

public class zutat_bearbeiten extends AppCompatActivity {

    public static final String LOG_TAG = hauptmenue.class.getSimpleName();
    private DbZugriff dbZugriff;

    //Schreiben in Datenbank
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zutat_bearbeiten);

        dbZugriff = new DbZugriff(this);

        GrundgeruestZutatenverwaltung datenCursor;

        Log.d(LOG_TAG, "Datenquelle wird geöffnet");
        dbZugriff.open();

        datenCursor = dbZugriff.createGrundgeruestZutatenverwaltung("Testprodukt", 2, "kg", 123);
        Log.d(LOG_TAG, "Es wurde der folgende Eintrag in die Datenbank geschrieben:");
        Log.d(LOG_TAG, "ID: " + datenCursor.getId() + ", Inhalt: " + datenCursor.toString());

        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");
        listenEintraegeZeigen();


        dbZugriff = new DbZugriff(this);

        Log.d(LOG_TAG, "Folgender Eintrag in Datenbank: ");
        Log.d(LOG_TAG, "ID" + datenCursor.getId()
                    +   "Zutat" + datenCursor.getZutat()
                    +   "Anzahl" + datenCursor.getAnzahl()
                    +   "Einheit" + datenCursor.getEinheit()
                    +   "Kcal" + datenCursor.getKcal());


        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");

        //Nullpointer Exception, kommt von Methode -> irrelevant
        listenEintraegeZeigen();

        Log.d(LOG_TAG, "Datenquelle wird geschlossen");
        dbZugriff.close();
    }

    private void listenEintraegeZeigen(){
        //Nullpointer Exception
        List<GrundgeruestZutatenverwaltung> zutatenListe =
                dbZugriff.getAllGrundgeruestZutatenverwaltung();

        ArrayAdapter<GrundgeruestZutatenverwaltung> zutatenverwaltungArrayAdapter =
                new ArrayAdapter<>(
                        this, android.R.layout.simple_list_item_multiple_choice,
                        zutatenListe);

        ListView zutatenListeAnsicht = findViewById(R.id.listview_zutaten);
        zutatenListeAnsicht.setAdapter(zutatenverwaltungArrayAdapter);
    }
}

以下是我通过浏览你的代码得到的信息! 您正在将查询输出的游标直接读取到您自己的模型类中,但您没有处理更糟糕的情况,即如果您的查询返回空游标怎么办!这可能是错误根目录的问题尝试此

   public GrundgeruestZutatenverwaltung createGrundgeruestZutatenverwaltung(
        String zutat, double anzahl, String einheit, int kcal) {
    ContentValues daten_zutat = new ContentValues();
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_ZUTAT, zutat);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_ANZAHL, anzahl);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_EINHEIT, einheit);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_KCAL, kcal);

    //nach id die Daten einfügen
    long idEinfuegen = database.insert(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, null, daten_zutat);

    Cursor cursor = database.query(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, columns,
            DbErzeugenUpdaten.COLUMN_ID + "=" + idEinfuegen, null, null, null, null);

if( cursor.moveToFirst()) {
// it means that your data is entered and cursor has first row to read
GrundgeruestZutatenverwaltung datenCursor = cursorToGrundgeruestZutatenverwaltung(cursor);
        cursor.close();
        return datenCursor;
}     else{
GrundgeruestZutatenverwaltung datenCursor = new GrundgeruestZutatenverwaltung(0,"NULL",0,"Null",0);
return datenCursor;
}
}
你可以在你的活动代码中做类似的事情来检查事情是否都好

//Schreiben in Datenbank
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zutat_bearbeiten);

        dbZugriff = new DbZugriff(this);

        GrundgeruestZutatenverwaltung datenCursor;

        Log.d(LOG_TAG, "Datenquelle wird geöffnet");
        dbZugriff.open();

        datenCursor = dbZugriff.createGrundgeruestZutatenverwaltung("Testprodukt", 2, "kg", 123);
        Log.d(LOG_TAG, "Es wurde der folgende Eintrag in die Datenbank geschrieben:");
        Log.d(LOG_TAG, "ID: " + datenCursor.getId() + ", Inhalt: " + datenCursor.toString());

        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");
        listenEintraegeZeigen();


        dbZugriff = new DbZugriff(this);

        Log.d(LOG_TAG, "Folgender Eintrag in Datenbank: ");
        Log.d(LOG_TAG, "ID" + datenCursor.getId()
                    +   "Zutat" + datenCursor.getZutat()
                    +   "Anzahl" + datenCursor.getAnzahl()
                    +   "Einheit" + datenCursor.getEinheit()
                    +   "Kcal" + datenCursor.getKcal());


        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");

        //Nullpointer Exception, kommt von Methode -> irrelevant
        listenEintraegeZeigen();

        Log.d(LOG_TAG, "Datenquelle wird geschlossen");
        dbZugriff.close();
    }//Schreiben in Datenbank
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zutat_bearbeiten);

        dbZugriff = new DbZugriff(this);

        GrundgeruestZutatenverwaltung datenCursor;

        Log.d(LOG_TAG, "Datenquelle wird geöffnet");
        dbZugriff.open();

        datenCursor = dbZugriff.createGrundgeruestZutatenverwaltung("Testprodukt", 2, "kg", 123);
       if((datenCursor.getZutat()).equalsIgnoreCase("NULL")){
          // no data found etc
       }
    }

除了试图访问dbZugriff=new dbZugriff(this)的最后一个类之外,其他一切似乎都很好;两次!!!为什么?在zutat_bearbeiten.javaI中删除了这一行,现在只剩下一条错误消息:at de.der_kalorienzaehler.kalorienzaehler.zutat_bearbeiten.onCreate(zutat_bearbeiten.java:26)这一行代码:dbZugriff.open();当我删除它时,在以下行中有一个NullPointerException:datenCursor=dbZugriff.createGrundgeruestZutatenverwaltung(“Testprodukt”,2,“kg”,123);但我很高兴,你解决了两个例外问题,GrundGeruestzutatenverwaltung??你的课程是定制的吗?您正在使用的?是的,我可以向您展示代码。我认为您需要添加一个自定义适配器。但是,在de.der_kalorienzaehler.kalorienzaehler.zutat_bearbeiten.onCreate(zutat_bearbeiten.java:26)中仍然存在错误:dbZugriff.open();因此,在我尝试open()之前,dbZugrifftry检查dbZugriff是否为null肯定是有问题的,但在下面的几行中仍然出现错误:datenCursor=dbZugriff.createGrundgeruestZutatenverwaltung(“Testprodukt”,2,“kg”,123);我自己解决了最后一个问题。感谢您对其他邮件的帮助:)很高兴知道,请将您的解决方案作为您自己的答案发布,以便将来也能帮助其他人
   public GrundgeruestZutatenverwaltung createGrundgeruestZutatenverwaltung(
        String zutat, double anzahl, String einheit, int kcal) {
    ContentValues daten_zutat = new ContentValues();
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_ZUTAT, zutat);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_ANZAHL, anzahl);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_EINHEIT, einheit);
    daten_zutat.put(DbErzeugenUpdaten.COLUMN_KCAL, kcal);

    //nach id die Daten einfügen
    long idEinfuegen = database.insert(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, null, daten_zutat);

    Cursor cursor = database.query(DbErzeugenUpdaten.TABLE_ZUTATENLISTE, columns,
            DbErzeugenUpdaten.COLUMN_ID + "=" + idEinfuegen, null, null, null, null);

if( cursor.moveToFirst()) {
// it means that your data is entered and cursor has first row to read
GrundgeruestZutatenverwaltung datenCursor = cursorToGrundgeruestZutatenverwaltung(cursor);
        cursor.close();
        return datenCursor;
}     else{
GrundgeruestZutatenverwaltung datenCursor = new GrundgeruestZutatenverwaltung(0,"NULL",0,"Null",0);
return datenCursor;
}
}
//Schreiben in Datenbank
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zutat_bearbeiten);

        dbZugriff = new DbZugriff(this);

        GrundgeruestZutatenverwaltung datenCursor;

        Log.d(LOG_TAG, "Datenquelle wird geöffnet");
        dbZugriff.open();

        datenCursor = dbZugriff.createGrundgeruestZutatenverwaltung("Testprodukt", 2, "kg", 123);
        Log.d(LOG_TAG, "Es wurde der folgende Eintrag in die Datenbank geschrieben:");
        Log.d(LOG_TAG, "ID: " + datenCursor.getId() + ", Inhalt: " + datenCursor.toString());

        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");
        listenEintraegeZeigen();


        dbZugriff = new DbZugriff(this);

        Log.d(LOG_TAG, "Folgender Eintrag in Datenbank: ");
        Log.d(LOG_TAG, "ID" + datenCursor.getId()
                    +   "Zutat" + datenCursor.getZutat()
                    +   "Anzahl" + datenCursor.getAnzahl()
                    +   "Einheit" + datenCursor.getEinheit()
                    +   "Kcal" + datenCursor.getKcal());


        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");

        //Nullpointer Exception, kommt von Methode -> irrelevant
        listenEintraegeZeigen();

        Log.d(LOG_TAG, "Datenquelle wird geschlossen");
        dbZugriff.close();
    }//Schreiben in Datenbank
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zutat_bearbeiten);

        dbZugriff = new DbZugriff(this);

        GrundgeruestZutatenverwaltung datenCursor;

        Log.d(LOG_TAG, "Datenquelle wird geöffnet");
        dbZugriff.open();

        datenCursor = dbZugriff.createGrundgeruestZutatenverwaltung("Testprodukt", 2, "kg", 123);
       if((datenCursor.getZutat()).equalsIgnoreCase("NULL")){
          // no data found etc
       }
    }