我试图将一些值插入到用户输入的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
答案 0 :(得分:1)
您的问题是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();
...
}
这将确保您设置成员变量而不是局部变量。