NumberFormatException: ноль

Я получаю эту ошибку:NumberFormatException: null когда я пытаюсь добавить счет/баллы в свое приложение.

Я создал для этого отдельную таблицу, потому что мне нужно несколько таблиц. Я понятия не имею, в чем проблема, так что спасибо вам всем.

  if (count==4) {

          my_db=new DBHelper(this);
          sqdb = my_db.getWritableDatabase();

          Cursor c_oldPoints= sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);
          int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
          c_oldPoints.moveToFirst();

          while (!c_oldPoints.isAfterLast())
             {
              OldPoints=c_oldPoints.getString(col_Points);
                            c_oldPoints.moveToNext();
             }
         sqdb.close();

         int OldP = Integer.parseInt(OldPoints);
         OldP+=countPoints;
         String SoldP = Integer.toString(OldP);
         my_db=new DBHelper(this);
         sqdb = my_db.getWritableDatabase();
         ContentValues cv = new ContentValues();
         cv.put(my_db.POINTS,SoldP);
         Cursor c = sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);

         c.moveToFirst();
         while (!c.isAfterLast())
         {
            sqdb.update(DBHelper.TABLE_NAME2,cv, DBHelper.POINTS+"=?",new String[]{OldPoints});
            c.moveToNext();
         }
         sqdb.close();
         countPoints=0;

  }

Это логарифм: -

2019-05-15 18:18:14.101 8513-8513/com.example.user.soundsequ E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.user.soundsequ, PID: 8513
    java.lang.NumberFormatException: null
        at java.lang.Integer.parseInt(Integer.java:483)
        at java.lang.Integer.parseInt(Integer.java:556)
        at com.example.user.soundsequ.Game.onClick(Game.java:353)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22429)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Можете ли вы опубликовать свой logcat?

Skizo-ozᴉʞS 15.05.2019 17:11
OldPoints может быть null, поэтому проверьте, что возвращает ваш запрос к базе данных.
Tom 15.05.2019 17:19

Skizo-ozᴉʞS я сделал то, что вы просили

Matan Lasry 15.05.2019 17:22

Том, как это сделать?

Matan Lasry 15.05.2019 18:00
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
4
101
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ошибка видимо в этой строке

int OldP = Integer.parseInt(OldPoints);

Ошибка говорит о том, что значение OldPoints не является строкой, которую можно преобразовать в целое число, например. если бы это было A или null;

Таким образом, либо значение, извлеченное из столбца POINTS, не является числовым, либо значение имени пользователя не соответствует столбцу NICKNAME в строке. В этом случае OldPoints будет любым значением, которое было установлено перед циклом.

Поскольку сами данные недоступны, вам необходимо выяснить, какая из двух ситуаций вызывает проблему.

Я бы предложил добавить несколько входов в систему, чтобы определить, какой из них.

например используя что-то вроде: -

      OldPoints = "my debugging value";
      Log.d("MYDEBUGGING","OldPoints, before doing anything is " + OldPoints);
      Cursor c_oldPoints= sqdb.query(DBHelper.TABLE_NAME2,null,DBHelper.NICKNAME+"=?",new String[]{Username},null,null,null);
      int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
      c_oldPoints.moveToFirst();

      while (!c_oldPoints.isAfterLast())
         {
          
          OldPoints=c_oldPoints.getString(col_Points);
                        c_oldPoints.moveToNext();
          Log.d("MYDEBUGGING","Extracted the value " + OldPoints + " from position + String.valueOf(c_oldPoints.getPosition());
         }
     sqdb.close();

     Log.d("MYDEBUGGING","Trying to convert the value " + OldPoints + " to an integer");
     int OldP = Integer.parseInt(OldPoints);

Вы также не можете внести вышеуказанные изменения и добавить точку останова (в первоначально указанной строке), а затем использовать приложение «Запустить/отладить» и проверить переменные (или использовать несколько точек останова в подходящих местах). Вы можете найти это полезным для отладки Отладка вашего приложения.

Следующий код защищает от исключения, а также от попытки обновить несуществующего пользователя:

    if (count == 4) {
        SQLiteDatabase sqdb = my_db.getWritableDatabase();

        Cursor c_oldPoints= sqdb.query(
                DBHelper.TABLE_NAME2,null,
                DBHelper.NICKNAME+"=?",
                new String[]{Username},
                null,null,null
        );
        int col_Points=c_oldPoints.getColumnIndex(DBHelper.POINTS);
        if (c_oldPoints.moveToFirst()) {
            Oldpoints = c_oldPoints.getString(col_Points);
            //Oldpoints = "oops";
            int OldP = 0;
            boolean can_convert_to_int = true;
            try {
                OldP = Integer.parseInt(Oldpoints) + countPoints;
                can_convert_to_int = true;
            } catch (NumberFormatException e) {
                e.printStackTrace(); //TODO not necessary probably remove. just for checking the log 
            }

            if (can_convert_to_int) {
                ContentValues cv = new ContentValues();
                cv.put(DBHelper.POINTS,OldP);
                sqdb.update(DBHelper.TABLE_NAME2,cv, DBHelper.NICKNAME + "=?", new String[]{Username});
            }
        } else {
            Log.d("NICKNAMENOTFOUND","No row was found when attemtping to get the old score for User " + Username);
        }
    }

Однако

Я бы посоветовал вам добавить пару методов в ваш класс DBHelper, а именно:

public int increasePoints(String user, int points_to_add) {
    SQLiteDatabase db = this.getWritableDatabase();
    SQLiteStatement sql = db.compileStatement(
            "UPDATE " + TABLE_NAME2 +
                    " SET " + POINTS + " = " + POINTS + " +?  " +
                    "WHERE "+ NICKNAME + "=?"
    );
    sql.bindLong(1,points_to_add);
    sql.bindString(2,user);
    return sql.executeUpdateDelete();
}

public int getPoints(String user) {
    SQLiteDatabase db = this.getWritableDatabase();
    int rv = -1;
    String whereclause = NICKNAME + "=?";
    String[] whereargs = new String[]{user};
    Cursor csr = db.query(TABLE_NAME2,new String[]{POINTS},whereclause,whereargs,null,null,null);
    if (csr.moveToFirst()) {
        rv = csr.getInt(csr.getColumnIndex(POINTS));
    }
    csr.close();
    return rv;
}

Первый метод увеличитьОчки выполняет изменение точек с помощью SQL-оператора UPDATE и избавляет от необходимости преобразовывать точки, извлеченные в виде строки, в целое число. Он возвращает количество обновленных строк (1, если столбец NICKNAME всегда является уникальным значением, 0, если ничего не обновлялось).

Второй метод получитьбаллы делает то, что он говорит, он получает очки для данного пользователя, если пользователь не существует, он возвращает -1.

Тогда ваш код может быть: -

    if (count == 4) {
        boolean updated = false; //TODO remove when happy
        int old_points = my_db.getPoints(Username); //TODO remove when happy
        if (my_db.increasePoints(Username,countPoints) > 0) {
            updated = true;
        }
        int new_points = my_db.getPoints(Username); //TODO remove when happy

        //TODO remove following code when happy
        String result = "The result of the attempt to update the points for user " + Username;
        if (updated) {
            result = result + " was successful. ";
        } else {
            result = result + " was unsuccessful.";
        }
        Log.d("POINTSINCREASE",result +
                " Points were " + String.valueOf(old_points) + " points are now " + String.valueOf(new_points));
    }

Примечание, где //TODO remove when happy закодировано, строки предназначены только для тестирования, поэтому приведенное выше может быть: -

    if (count == 4) {
        my_db.increasePoints(Username,countPoints);
    }

Другие вопросы по теме