Исключение нулевого указателя Android SQLite

Я получаю это в LogCat:

05-20 17:16:34.721: E/AndroidRuntime(30461): FATAL EXCEPTION: main
05-20 17:16:34.721: E/AndroidRuntime(30461): java.lang.NullPointerException
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1810)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1761)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at com.kickinglettuce.debtplannerpro.DebtDataSource.updateDebt(DebtDataSource.java:130)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at com.kickinglettuce.debtplannerpro.manageDebts$4.onClick(manageDebts.java:184)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.view.View.performClick(View.java:3511)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.view.View$PerformClick.run(View.java:14105)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.os.Handler.handleCallback(Handler.java:605)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.os.Looper.loop(Looper.java:137)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at android.app.ActivityThread.main(ActivityThread.java:4447)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at java.lang.reflect.Method.invokeNative(Native Method)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at java.lang.reflect.Method.invoke(Method.java:511)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-20 17:16:34.721: E/AndroidRuntime(30461):    at dalvik.system.NativeStart.main(Native Method)

Вот код, связанный с ним:

protected void onListItemClick(ListView l, View v, int position, long id) {

    List<Debt> values = datasource.getAllDebt();
            datasource.open();

    Debt item = values.get(position);
    final long boxId = item.getId();
    // final String BoxId = String.valueOf(boxId);
    final String BoxName = item.getName();
    final String BoxBalance = item.getBalance();
    final String BoxApr = item.getApr();
    final String BoxPayment = item.getPayment();

    // set up dialog
    final Dialog dialog = new Dialog(manageDebts.this);
    dialog.setContentView(R.layout.custom_dialog);
    dialog.setTitle("Edit Debt Details");
    dialog.setCancelable(true);

    // set up text
    TextView tv1 = (TextView) dialog.findViewById(R.id.textView1);
    TextView tv2 = (TextView) dialog.findViewById(R.id.textView2);
    TextView tv3 = (TextView) dialog.findViewById(R.id.textView3);
    TextView tv4 = (TextView) dialog.findViewById(R.id.textView4);
    EditText et1 = (EditText) dialog.findViewById(R.id.editText1);
    EditText et2 = (EditText) dialog.findViewById(R.id.editText2);
    EditText et3 = (EditText) dialog.findViewById(R.id.editText3);
    EditText et4 = (EditText) dialog.findViewById(R.id.editText4);

    tv1.setText("Debt Description");
    tv2.setText("Balance");
    tv3.setText("APR");
    tv4.setText("Monthly Payment");

    et1.setText(BoxName);
    et2.setText(BoxBalance);
    et3.setText(BoxApr);
    et4.setText(BoxPayment);

    // set up button
    Button button = (Button) dialog.findViewById(R.id.button1);
    button.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {


            datasource.updateDebt(Long.valueOf(boxId), BoxName, BoxBalance, BoxApr,
                    BoxPayment);
            dialog.dismiss();

        }
    });

    datasource.close();

    dialog.show();
}

И метод обновления в моем классе базы данных:

public boolean updateDebt(long updateId, String debtName, String debtTotal,
        String debtApr, String paymentGoal) {

     ContentValues values = new ContentValues();
     values.put(MySQLiteHelper.COLUMN_DEBT_NAME, debtName);
     values.put(MySQLiteHelper.COLUMN_DEBT_TOTAL, debtTotal);
     values.put(MySQLiteHelper.COLUMN_APR, debtApr);
     values.put(MySQLiteHelper.COLUMN_PAYMENT, paymentGoal);
     String whereClause = MySQLiteHelper.COLUMN_ID + " = ?";
     String[] whereArgs = new String[]{ String.valueOf(updateId) };
     return database.update(MySQLiteHelper.TABLE_DEBT,
             values, whereClause, whereArgs) > 0;
}

Какие-либо предложения?


person TheLettuceMaster    schedule 21.05.2012    source источник
comment
Где вы вызываете datasource.open()?   -  person Rymnel    schedule 21.05.2012
comment
Ну, я просто добавил его под List‹Debt› values ​​= datasource.getAllDebt(); И получил ту же ошибку. (изменить: только что обновил код, чтобы показать)   -  person TheLettuceMaster    schedule 21.05.2012
comment
Где вы вызываете datasource.open() и datasource.close()?   -  person Rymnel    schedule 21.05.2012
comment
Вы создали экземпляр datasource?   -  person Phix    schedule 21.05.2012
comment
В методе onCreate того же класса.   -  person TheLettuceMaster    schedule 21.05.2012


Ответы (2)


Похоже, вы пытаетесь получить доступ к базе данных, когда она была закрыта. Возможно, размещение datasource.open() в начале onCreate и datasource.close() в конце onCreate() и вызов их только один раз в вашем классе решит вашу проблему.

Если вы редактируете, создаете и удаляете элементы в своей деятельности, требующие многократных обращений к вашей базе данных, рассмотрите возможность вызова datasource.open() в начале метода, который обращается к базе данных, а затем close() в конце этого метода.

person Rymnel    schedule 21.05.2012
comment
Это сработало отлично. Также было похоже, что я вызывал Open/Close слишком много раз. - person TheLettuceMaster; 21.05.2012
comment
Чем это отличается от добавления открытой и закрытой таблицы в начале и конце активности??? - person Basavaraj Hampali; 30.07.2013
comment
@BasavarajHampali Это тоже приемлемый вариант. Возможно, открытие onStart() и закрытие onPause() также сработает. Общая идея заключается в том, чтобы открывать и закрывать только один раз в ходе деятельности. - person Rymnel; 01.08.2013

Лучше всего использовать класс SQLiteOpenHelper, который заботится о предоставлении экземпляра SQLiteDatabase, это одноэлементный шаблон:

см. Android: java.lang.IllegalStateException: база данных xxx.db (conn# 0) уже закрыт

person Miloš    schedule 14.11.2012