为什么我要问:我不想听起来很粗鲁,但我非常绝望。我试过这些东西,你已经在几个问题中描述了大约8个小时,但是我没有得到其他人的帮助而得不到它。我理解NullPointerExceptions的理论和你的例子,但我不知道如何做得更好,特别是与一个效果相当的例子相比。我在数据库中只修改了我的表的几个变量,我需要一些关于我的案例的解释。我不会问,我是否可以自己找到答案。请帮我解决我的问题。
我尝试学习Android编程。为了做到这一点,我使用了一个解释如何创建SQLite数据库的教程。
虽然我使用作者之一检查了我的代码并检查了有关此错误的Stack Overflow,但我还没有找到我的错误。
当我测试我的应用程序时,我的Logcat中有以下内容:
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"依赖于光标的值,因此不需要更改它们。我尝试按照我的班级中名为" dbErzeugenUpdaten"的其他帖子中的建议初始化数据库。但是,当我尝试时,有一个无限循环或我无法初始化它,因为它已经存在。
所以我的问题是,为了避免NullPointerException,我必须编写什么?也许我错了我的问题的根源,所以我告诉你这个班" zutat_bearbeiten"同样,如果Cursor的问题解决了,那么这个类应该没问题?
我期待着你的帮助。
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;
}
}
我通过修改这个类来创建我的课程(当我尝试时它运作良好):
package de.programmierenlernenhq.shoppinglisthq;
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 ShoppingMemoDataSource {
private static final String LOG_TAG = ShoppingMemoDataSource.class.getSimpleName();
private SQLiteDatabase database;
private ShoppingMemoDbHelper dbHelper;
private String[] columns = {
ShoppingMemoDbHelper.COLUMN_ID,
ShoppingMemoDbHelper.COLUMN_PRODUCT,
ShoppingMemoDbHelper.COLUMN_QUANTITY
};
public ShoppingMemoDataSource(Context context) {
Log.d(LOG_TAG, "Unsere DataSource erzeugt jetzt den dbHelper.");
dbHelper = new ShoppingMemoDbHelper(context);
}
public void open() {
Log.d(LOG_TAG, "Eine Referenz auf die Datenbank wird jetzt angefragt.");
database = dbHelper.getWritableDatabase();
Log.d(LOG_TAG, "Datenbank-Referenz erhalten. Pfad zur Datenbank: " + database.getPath());
}
public void close() {
dbHelper.close();
Log.d(LOG_TAG, "Datenbank mit Hilfe des DbHelpers geschlossen.");
}
public ShoppingMemo createShoppingMemo(String product, int quantity) {
ContentValues values = new ContentValues();
values.put(ShoppingMemoDbHelper.COLUMN_PRODUCT, product);
values.put(ShoppingMemoDbHelper.COLUMN_QUANTITY, quantity);
long insertId = database.insert(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST, null, values);
Cursor cursor = database.query(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST,
columns, ShoppingMemoDbHelper.COLUMN_ID + "=" + insertId,
null, null, null, null);
cursor.moveToFirst();
ShoppingMemo shoppingMemo = cursorToShoppingMemo(cursor);
cursor.close();
return shoppingMemo;
}
private ShoppingMemo cursorToShoppingMemo(Cursor cursor) {
int idIndex = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_ID);
int idProduct = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_PRODUCT);
int idQuantity = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_QUANTITY);
String product = cursor.getString(idProduct);
int quantity = cursor.getInt(idQuantity);
long id = cursor.getLong(idIndex);
ShoppingMemo shoppingMemo = new ShoppingMemo(product, quantity, id);
return shoppingMemo;
}
public List<ShoppingMemo> getAllShoppingMemos() {
List<ShoppingMemo> shoppingMemoList = new ArrayList<>();
Cursor cursor = database.query(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST,
columns, null, null, null, null, null);
cursor.moveToFirst();
ShoppingMemo shoppingMemo;
while(!cursor.isAfterLast()) {
shoppingMemo = cursorToShoppingMemo(cursor);
shoppingMemoList.add(shoppingMemo);
Log.d(LOG_TAG, "ID: " + shoppingMemo.getId() + ", Inhalt: " + shoppingMemo.toString());
cursor.moveToNext();
}
cursor.close();
return shoppingMemoList;
}
}
dbErzeugenUpdaten类:
//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) {
}
}
zutat_bearbeiten上课:
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);
}
}
grundgeruestZutatenverwaltung上课:
//Daten aus der Datenbank werden als Java Objekte gespeichert, Zugriff auf Variablen mit GETTER und SETTER
package de.der_kalorienzaehler.kalorienzaehler;
import android.database.Cursor;
public class GrundgeruestZutatenverwaltung {
//Objekte sind private, um Zugriffsmöglichkeiten von außen einzudämmen
private long id;
private String zutat;
private double anzahl;
private String einheit;
private int kcal;
//Konstruktor, Objekte werden erzeugt im Speicher
public GrundgeruestZutatenverwaltung(long id, String zutat, double anzahl,
String einheit, int kcal){
this.id = id;
this.zutat = zutat;
this.anzahl = anzahl;
this.einheit = einheit;
this.kcal = kcal;
}
//getter: abrufen
public long getId(){
return id;
}
//setter: überschreiben
public void setId(long id){
this.id = id;
}
public String getZutat(){
return zutat;
}
public void setZutat(String zutat){
this.zutat = zutat;
}
public double getAnzahl(){
return anzahl;
}
public void setAnzahl(double anzahl){
this.anzahl = anzahl;
}
public String getEinheit(){
return einheit;
}
public void setEinheit(String einheit){
this.einheit = einheit;
}
public int getKcal(){
return kcal;
}
public void setKcal(int kcal){
this.kcal = kcal;
}
@Override
public String toString(){
String ausgabe = zutat + "-" + anzahl + "-" + einheit + "-" + kcal;
return ausgabe;
}
}
答案 0 :(得分:0)
这是我通过浏览代码到目前为止所得到的! 你直接将查询输出的光标读入你自己的模型类,但是你没有处理更糟糕的情况,如果你的查询返回一个空光标怎么办!这可能是错误root的问题尝试这个
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;
}
}
你可以在ACTIVITY CODE OF YOURS中做同样的事情来检查事情是否都很好
//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
}
}