SQLiteOpenHelper构造函数未被调用

时间:2016-06-12 02:30:56

标签: android nullpointerexception android-sqlite sqliteopenhelper

我正在使用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语法。应用程序现在运行没有问题。谢谢大家的帮助!

1 个答案:

答案 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数据库的完整部分。这也可以解决您的问题。