我正在使用SQLiteOpenHelper
创建应用。当我为这个类创建一个对象时,没有调用构造函数,当我使用它的方法时会导致NullPointerException
。这是我的DatabaseHandler
课程:
class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "INVENTORY_MANAGER";
private static final String TABLE_NAME = "INVENTORY";
private static final String KEY_ID = "id";
private static final String KEY_ITEM_NAME = "name";
private static final String KEY_ITEM_PRICE = "price";
private static final String KEY_ITEM_COUNT = "count";
private static final String KEY_ITEM_SOLD = "sold";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(final SQLiteDatabase db) {
final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME
+ "( " + KEY_ID + " INTEGER PRIMARY KEY, "
+ KEY_ITEM_NAME + " TEXT, "
+ KEY_ITEM_PRICE + " TEXT, "
+ KEY_ITEM_COUNT + " TEXT, "
+ KEY_ITEM_SOLD + " TEXT )";
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addItem(final Item item) {
final SQLiteDatabase db = this.getWritableDatabase();
final ContentValues contentValues = new ContentValues();
contentValues.put(KEY_ITEM_NAME, item.getItemName());
contentValues.put(KEY_ITEM_PRICE, item.getItemPrice());
contentValues.put(KEY_ITEM_COUNT, item.getItemCount());
contentValues.put(KEY_ITEM_SOLD, item.getItemSold());
long id = db.insert(TABLE_NAME, null, contentValues);
Log.i("LOG", "" + id);
db.close();
}
List<Item> getItems() {
final List<Item> items = new ArrayList<>();
final String SELECT_QUERY = "SELECT * FROM " + TABLE_NAME;
final SQLiteDatabase db = getReadableDatabase();
final Cursor cursor = db.rawQuery(SELECT_QUERY, null);
if ( cursor.moveToFirst() ) {
do {
final Item item = new Item();
item.setId(Integer.parseInt(cursor.getString(0)));
item.setItemName(cursor.getString(1));
item.setItemPrice(cursor.getString(2));
item.setItemCount(cursor.getString(3));
item.setItemSold(cursor.getString(4));
} while ( cursor.moveToNext() );
}
cursor.close();
return items;
}
}
这是我主要活动中的代码:
public class MainActivity extends AppCompatActivity {
private List<Item> items;
private ItemsListAdapter adapter;
private DatabaseHandler handler;
@Override
public void onCreate(final Bundle savedInstanceState, final PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_main);
items = new ArrayList<>();
final View emptyView = getLayoutInflater().inflate(R.layout.list_item_empty, null, false);
addContentView(emptyView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
final ListView itemList = (ListView) findViewById(R.id.itemList);
handler = new DatabaseHandler(this);
items.addAll(handler.getItems());
adapter = new ItemsListAdapter(items, getApplicationContext());
if (itemList != null) {
itemList.setAdapter(adapter);
itemList.setEmptyView(emptyView);
itemList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
}
});
}
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (item.getItemId() == R.id.action_add_item) {
final View dialogView = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_add_item, null);
final EditText addItemName = (EditText) dialogView.findViewById(R.id.addItemName);
final EditText addItemPrice = (EditText) dialogView.findViewById(R.id.addItemPrice);
final EditText addItemCount = (EditText) dialogView.findViewById(R.id.addItemCount);
final EditText addItemSold = (EditText) dialogView.findViewById(R.id.addItemSold);
final AlertDialog.Builder itemAdder = new AlertDialog.Builder(new ContextThemeWrapper(MainActivity.this, R.style.Dialog));
itemAdder.setTitle("Add Item");
itemAdder.setMessage("Enter details about the new item");
itemAdder.setView(dialogView);
itemAdder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
final Item item = new Item();
final String itemName = addItemName.getText().toString().trim();
String itemPrice = addItemPrice.getText().toString().trim();
String itemCount = addItemCount.getText().toString().trim();
String itemSold = addItemSold.getText().toString().trim();
item.setItemName(itemName);
item.setItemPrice(itemPrice);
item.setItemCount(itemCount);
item.setItemSold(itemSold);
//This is where I get the error
/*java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List aakaashjois.inventoryapp.DatabaseHandler.addItem(item)' on a null object reference */
handler.addItem(item);
items.clear();
items.addAll(handler.getItems());
adapter.notifyDataSetChanged();
}
}
});
itemAdder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
dialog.dismiss();
}
});
itemAdder.create().show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
当我收到错误时,这是我的日志:
06-15 11:46:11.880 29965-29980/aakaashjois.inventoryapp I/art: Background partial concurrent mark sweep GC freed 1717(388KB) AllocSpace objects, 0(0B) LOS objects, 39% free, 1579KB/2MB, paused 10.377ms total 30.998ms
06-15 11:46:11.904 29965-29965/aakaashjois.inventoryapp I/ViewRootImpl: CPU Rendering VSync enable = true
06-15 11:46:19.049 29965-29965/aakaashjois.inventoryapp D/AndroidRuntime: Shutting down VM
06-15 11:46:19.051 29965-29965/aakaashjois.inventoryapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: aakaashjois.inventoryapp, PID: 29965
java.lang.NullPointerException: Attempt to invoke virtual method 'void aakaashjois.inventoryapp.DatabaseHandler.addItem(aakaashjois.inventoryapp.Item)' on a null object reference
at aakaashjois.inventoryapp.MainActivity$2.onClick(MainActivity.java:108)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:157)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
06-15 11:46:19.115 29965-29965/aakaashjois.inventoryapp I/Process: Sending signal. PID: 29965 SIG: 9
根据我收到的反馈,我删除了SQLiteOpenHelper
类并编写了没有该类的SQLite语法。应用程序现在运行没有问题。谢谢大家的帮助!
答案 0 :(得分:1)
创建一个名为DatabaseAdapter
的新类。将以下代码添加到其中:
public class DatabaseAdapter {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "INVENTORY_MANAGER";
private static final String TABLE_NAME = "INVENTORY";
private static final String KEY_ID = "id";
private static final String KEY_ITEM_NAME = "name";
private static final String KEY_ITEM_PRICE = "price";
private static final String KEY_ITEM_COUNT = "count";
private static final String KEY_ITEM_SOLD = "sold";
private Context context;
SQLiteDatabase database;
DatabaseHelper helper;
public DatabaseAdapter(Context context) {
this.context = context;
this.helper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME
+ "( " + KEY_ID + " INTEGER PRIMARY KEY, "
+ KEY_ITEM_NAME + " TEXT, "
+ KEY_ITEM_PRICE + " TEXT, "
+ KEY_ITEM_COUNT + " TEXT, "
+ KEY_ITEM_SOLD + " TEXT)");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("Database", “Upgrading database from version “ + oldVersion + “ to “ + newVersion + “, which will destroy all old data”);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
public DatabaseAdapter open() throws SQLException {
this.database = DBHelper.getWritableDatabase();
return this;
}
public void close() {
DatabaseHelper.close();
}
public long addItem(final Item item) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_ITEM_NAME, item.getItemName());
contentValues.put(KEY_ITEM_PRICE, item.getItemPrice());
contentValues.put(KEY_ITEM_COUNT, item.getItemCount());
contentValues.put(KEY_ITEM_SOLD, item.getItemSold());
return database.insert(TABLE_NAME, null, contentValues);
}
// Add the rest of your code here
}
在您的主要活动中,您现在可以引用您的DatabaseAdapter
课程:
DatabaseAdapter database = new DatabaseAdapter(this);
database.open();
// call any of the functions that you need
long insert = database.addItem(Item parametre);
database.close();
另外,请查看this电子书,其中包含有关SQLite数据库的完整部分。这也可以解决您的问题。