Nullpointerexception при попытке вставить значение в SQLite - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь вставить некоторые значения в базу данных SQLite, которые вводит пользователь, однако, когда я нажимаю кнопку, чтобы сохранить значения, происходит сбой и возникает исключение NullPointer:

java.lang.NullPointerException: Attempt to invoke virtual method 'long android.database.sqlite.SQLiteDatabase.insert(java.lang.String, java.lang.String, android.content.ContentValues)' on a null object reference at com.example.w4e74.farmanimalfinal.DatabaseHelper.insertRecord(DatabaseHelper.java:61)at com.example.w4e74.farmanimalfinal.Activity_item.onOptionsItemSelected(Activity_item.java:66)

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

Activity_item.java

package com.example.w4e74.farmanimalfinal;

import android.app.Dialog;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewDebug;
import android.widget.EditText;
import android.widget.ListView;

public class Activity_item extends AppCompatActivity {

EditText editText_item;
boolean newItem;
long item_index;

private SQLiteDatabase db;
private Cursor cursor;
CustomCursorAdapter listAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_item);

    DatabaseHelper db = new DatabaseHelper(this);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_item);
    setSupportActionBar(toolbar);

    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);



    Intent intent = getIntent();
    item_index = intent.getLongExtra("item_index", -1);

    if(item_index == -1) {
        newItem = true;
    } else {

        newItem = false;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_item, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.save_item:


            DatabaseHelper.insertRecord(db, (R.id.editText_date),(R.id.editText_time), Integer.toString(R.id.editText_staff),(R.id.editText_animal),Integer.toString(R.id.editText_activity),Integer.toString(R.id.editText_details));

            finish();
            return true;


        default:
            return super.onOptionsItemSelected(item);
    }
}

}

DatabaseHelper.java

package com.example.w4e74.farmanimalfinal;

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

public class DatabaseHelper extends SQLiteOpenHelper {

private static final String DB_NAME = "farmanimals";

private static final int DB_VERSION = 1;

public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE RECORD ("
            + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + "DATE INTEGER, "
            + "TIME INTEGER, "
            + "STAFF TEXT,"
            + "ANIMAL INTEGER,"
            + "ACTIVITY TEXT,"
            + "DETAIL TEXT);"
    );



}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}

@Override
public void onDowngrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {


}


public static long insertRecord(SQLiteDatabase db, int date, int time, String staff, int animal, String activity, String detail ) {

    ContentValues recordValues = new ContentValues();


    recordValues.put("DATE", date);
    recordValues.put("TIME", time);
    recordValues.put("STAFF", staff);
    recordValues.put("ANIMAL", animal);
    recordValues.put("ACTIVITY", activity);
    recordValues.put("DETAIL", detail);


    long newRecordID = db.insert("RECORD", null, recordValues);

    return newRecordID;
}

public static String getDatabaseContentsAsString(SQLiteDatabase db) {

    Cursor cursor = db.query("RECORD",
            new String[]{"_id", "DATE", "TIME", "STAFF", "ANIMAL", "ACTIVITY", "DETAIL"},
            null, null, null, null, "_id ASC");

    String databaseAsString = System.getProperty("line.separator");

    if(cursor.getCount() != 0) {
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            for (int i=0; i < cursor.getColumnCount() - 1; i++) {
                databaseAsString += cursor.getString(i) + "     ";
            }
            databaseAsString += System.getProperty("line.separator");
            cursor.moveToNext();
        }

        if(cursor != null) cursor.close();
    }

    return databaseAsString;
}


public static void deleteRecord(SQLiteDatabase db, Long id) {
    db.delete("RECORD", "_id=?", new String[] {Long.toString(id)});
}

public static void deleteAllRecords(SQLiteDatabase db) {
    db.delete("RECORD", null, null);
    db.delete("SQLITE_SEQUENCE","NAME = ?",new String[]{"RECORD"});
}

}

Редактировать: Сообщение об ошибке получено:

Incompatible types.
Required:
android.database.sqlite.SQLiteDatabase
Found:
com.example.w4e74.farmanimalfinal.DatabaseHelper

1 Ответ

0 голосов
/ 06 июня 2018

Ваша проблема - область действия db В onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_item);

    DatabaseHelper db = new DatabaseHelper(this);

    ...
}

Этот экземпляр db объявлен как локальная переменная, эффективно создающая две переменные, оба называются db, но работают в разных областях.Это означает, что, как только onCreate() будет завершено, эта ссылка на db будет потеряна, а мусор будет собран.

Ваши два экземпляра db также бывают разных типов - SQLiteDatabase и DatabaseHelper, поэтому лучшая стратегия именования переменных поможет избежать подобных проблем в будущем.Поскольку мы будем использовать SQLiteDatabase версию db, нам потребуется захватить доступный для записи экземпляр вашей базы данных для использования с помощником в будущем:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_item);

    db = new DatabaseHelper(this).getWritableDatabase();

    ...
}

Это гарантирует, что вынастраиваете переменную-член, а не локальную переменную.

...