2

Ich erstelle eine App mit der SQLiteOpenHelper. Wenn ich ein Objekt für diese Klasse erstelle, wird der Konstruktor nicht aufgerufen, was zu einem NullPointerException führt, wenn ich seine Methoden verwende. Hier ist meine DatabaseHandler Klasse:SQLiteOpenHelper-Konstruktor wird nicht aufgerufen

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

Dies ist der Code in meiner Haupttätigkeit:

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

Hier ist mein log, wenn ich den Fehler:

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 

Basierend auf dem Feedback Ich erhielt, ich entfernte die Klasse SQLiteOpenHelper und schrieb die SQLite-Syntax ohne diese Klasse. Die Anwendung läuft jetzt ohne Probleme. Vielen Dank für die Hilfe!

+0

zeigen Sie Ihre Logcat .. !! –

+0

Ich habe den Logcat –

+0

hinzugefügt, Sie erhalten keinen Fehler bei 'handler.getItems()' erste Zeile nach 'handler = new DatabaseHandler (this);' ?? –

Antwort

1

Erstellen Sie eine neue Klasse namens DatabaseAdapter. Fügen Sie den folgenden Code hinzu:

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 
} 

In Ihrer Haupttätigkeit, können Sie jetzt Ihre DatabaseAdapter Klasse als so Referenz:

DatabaseAdapter database = new DatabaseAdapter(this); 
database.open(); 

// call any of the functions that you need 
long insert = database.addItem(Item parametre); 

database.close(); 

Auch einen Blick auf this eBook, die auf einen etire Schnitt SQLite-Datenbanken. Dies könnte auch Ihr Problem beheben.

+0

Ich habe immer noch den gleichen Fehler. –

+0

Ich denke, es ist wegen des übrig gebliebenen Codes, den Sie haben, dass die 'DatabaseHelper'-Klasse sich jetzt um Sie kümmert. Ich werde die Antwort mit dem neuen Code aktualisieren. – Razor

+0

Sehen Sie sich die neue 'addItem'-Funktion an. Es wird automatisch einen "langen" Wert zurückgegeben. Sie müssen eine 'long'-Variable initialisieren und dann die Funktion aufrufen, um ein Element hinzuzufügen. – Razor