-1

I'm trying to insert some values into an SQLite Database which are entered by the user, however when I press the button to save the values it crashes and a NullPointer exception is thrown:

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)

I do not know what is causing the exception. My code is below, any help would be very appreciated.

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"});
}

}

Edit: Error message received:

Incompatible types.
Required:
android.database.sqlite.SQLiteDatabase
Found:
com.example.w4e74.farmanimalfinal.DatabaseHelper
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Phantômaxx Jun 06 '18 at 15:43

1 Answers1

2

Your problem is the scope of db In onCreate():

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

    DatabaseHelper db = new DatabaseHelper(this);

    ...
}

You have this instance of db declared as a local variable, effectively creating two variables, both called db but operating at different scopes. This means that as soon as onCreate() is finished, this reference to db will be lost and garbage collected.

Your two instances of db are also of different types - SQLiteDatabase and DatabaseHelper, so a better variable naming strategy would help avoid problems like this in the future. As we'll be using the SQLiteDatabase version of db, we'll need to grab a writable instance of your database to use with the helper in future:

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

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

    ...
}

This will ensure that you're setting the member variable rather than a local variable.

Michael Dodd
  • 10,102
  • 12
  • 51
  • 64