#java #android
#java #Android
Вопрос:
Я создаю приложение, в котором пользователь вводит от 7 до 10 числовых значений в нескольких действиях. Затем записи используются в довольно многоуровневом уравнении, которое возвращает результат пользователю. Два значения доставляют мне проблемы и создают NumberFormatException
то, что я не могу понять.
Одна запись IHCValue
выбирается из счетчика, поскольку существует только 4 возможных варианта:
<string-array name="ihc_choices">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
Этот выбор не только используется в уравнении, но и определяет, требуется ли дополнительная информация.
Получение значения IHCValue:
private void directSpinner(){
int spinnerPosition = scoreSelect.getSelectedItemPosition();
String[] IHC_Values = getResources().getStringArray(R.array.ihc_choices);
String IHCValue = String.valueOf(IHC_Values[spinnerPosition]);
SharedPrefManager.write(IHC_VALUE, IHCValue);
//The string to manage Intent defined separately as the intent did not recognize the value of 'String IHCValue'
String IHCEntry = scoreSelect.getSelectedItem().toString();
if (IHCEntry.equals("2")){
//Status equivocal, must collect more information before calculation can be performed.
Intent next = new Intent(getApplicationContext(), FishScoreActivity.class);
startActivity(next);
} else { //IHCValue of 0,1,3
//Status is defined, we have enough info to perform calculation.
Intent last = new Intent(getApplicationContext(), CancerDemographicActivity.class);
startActivity(last);
}
}
Если пользователь выбирает «2» из этого выпадающего списка, запрашивается следующее действие FISHEntry
, также используемое в части уравнения:
Получение FISHEntry:
public boolean validateData(){
boolean validData = false;
String FISHEntry = enterFISH.getText().toString();
if (!FISHEntry.equals("")){
SharedPrefManager.write(FISH_RATIO, FISHEntry);
validData = true;
} else {
Toast.makeText(getApplicationContext(), "Please enter FISH ratio from your report.", Toast.LENGTH_LONG).show();
validData = false;
}
return validData;
}
Затем пользователь может нажать кнопку и запустить уравнение. Если пользователь выбрал IHCValue
значение 0,1 или 3 FISHEntry
, оно не требуется, и уравнение выполняется нормально.
Если (и только если), IHCValue = 2
то в классе Equation необходимо выполнить дополнительное вычисление, что приведет к сбою приложения.
Шаги, которые я выполнил из приложения:
- Из счетчика
IHCValue
выбрано значение 2. - Предлагается ввести оценку РЫБЫ,
FISHEntry = 2.3
- Нажмите кнопку «Рассчитать»:
Затем приложение выходит из строя:
Caused by: java.lang.NumberFormatException: Invalid int: "2.3"
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parse(Integer.java:410)
at java.lang.Integer.parseInt(Integer.java:367)
at java.lang.Integer.parseInt(Integer.java:334)
at com.them.health.Equations.MasterEquation.<clinit>
(MasterEquation.java:42)
«2.3» — это моя FISHEntry
строка while 42, которая объявляет IHCValue
:
MasterEquation.java:42
private static int mIHCValue = Integer.parseInt(SharedPrefManager.read(IHC_VALUE, null));
FISHEntry is declared on MasterEquation.java:41:
private static double mFISHRatio = Double.valueOf(SharedPrefManager.read(FISH_RATIO, null));
To be consistent, all values are saved to SharedPrefs as string and I parse int or double as needed when the equation is performed. Also, I received a String-to-Integer error when saving the IHCValue
directly as an int.
Method in MasterEquation.java which uses the variables:
private void calcRatioOne(){
double innerRatio = mIHCValue/mFISHRatio;
if (mIHCValue == 0 || mIHCValue == 1){
mRatioOne = 0.0;
} else if (mIHCValue == 3){
mRatioOne = 12.75525;
} else if (mIHCValue == 2){ //IHC = 2 takes FISHEntry into account.
if (innerRatio >= 2.2){
mRatioOne = 12.75525;
}
if (innerRatio >= 1.8){
mRatioOne = 1.46495;
}
if (innerRatio < 1.8){
mRatioOne = 0.0;
}
}
}
private double mRatioOne;
определяется в начале.
Я попробовал следующее:
- Записывайте значения в SharedPrefs как int / float, когда пользователь вводит их. Ошибка преобразования в double при запуске equation.
- Создан метод специально для обработки
innerRatio
вычислений. Та же проблема. - Объявляйте и обрабатывайте значение IHCValue как double / float . Та же проблема.
- Объявлено IHCValue как
Integer
вместоint
. Та же проблема.
Это проблема только тогда, когда IHCValue = 2
Я не против изменения записи IHC с счетчика на другой метод ввода, если это поможет, но хотел бы избежать свободного текста, поскольку это самая важная запись в последовательности.
Мой SharedPrefManager:
Объявленный ключ:
public static final String IHC_VALUE = null;
Метод чтения и записи:
public static String read(String key, String defValue){
return userPrefs.getString(key, defValue);
}
public static void write(String key, String value) {
SharedPreferences.Editor prefsEditor = userPrefs.edit();
prefsEditor.putString(key, value);
prefsEditor.commit();
}
Комментарии:
1. Вы пробовали запускать ее с помощью отладчика?
2. Хотя это довольно просто:
Caused by: java.lang.NumberFormatException: Invalid int: "2.3"
пожалуйста, измените3. @Shark Я ценю ответ. Сначала я не был уверен, с чего начать вопрос — отсутствие опыта отладки этому не помогло. Я провел все это утро, изучая отладчик. ВАУ! Удивительно полезно и проницательно. Я могу сказать, что это уже уменьшит количество вопросов, которые мне нужно задать здесь и моим друзьям.
4. @Shark Я краду твою цитату :)! Просто дополнение здесь: используйте IDE для написания кода. Всегда. Это значительно упрощает обнаружение ошибок и разработку хорошего, качественного кода. Моим личным фаворитом и в целом популярной IDE является IntelliJ . Существует бесплатная версия, но если вы студент, вам разрешено бесплатно использовать конечную версию. Инструмент отладчика этой IDE прост в освоении, а также очень хорош. (То, что Shark раньше называл отладчиком, на самом деле является компилятором JVM, выдающим сообщение об ошибке)
5. @P.Soutzikevich Спасибо! Я все делаю в Android Studio, но не был настолько блаженным, не зная об инструменте отладки. Абсолютно поразило меня — до этого у меня была деятельность, целью которой было присвоить моим переменным EditText, чтобы убедиться, что они верны, очень подход Рубе Голдберга.
Ответ №1:
Из сообщения об ошибке очевидно, в чем проблема. Вы пытаетесь присвоить значение «2.3» переменной целочисленного типа.
Лучшим решением было бы использовать инструмент отладчика, предлагаемый в большинстве интегрированных сред разработки (IDE), таких как IntelliJ или Eclipse. С помощью этого инструмента отладчика выясните, почему изначально присвоено неправильное значение
IHCValue
, и действуйте соответствующим образом, чтобы устранить ошибку.
Я не согласен с исправлением, предложенным в комментариях @shark; назначение a Float
для an int
является несовместимой операцией. Мое предложение — изменить тип mIHCValue на double
.
Если mIHCValue должно быть целым числом, затем преобразуйте его из строки в double, а затем преобразуйте как целое число. Вот так:
private double originalIHC = Double.valueOf(SharedPrefManager.read(IHC_VALUE, null));
private static int mIHCValue = (int) originalIHC;
Позвольте мне объяснить, почему я сделал это в 2 строках. Поскольку значение строки является не целым числом, а числом с плавающей запятой, мы должны сначала проанализировать его как double . Но преобразовать строку в примитив double
невозможно, поэтому мы должны использовать класс-оболочку Double
для этого.
Класс-оболочка Double
(бокс) несовместим с примитивным типом, отличным от double
, поэтому мы сначала присваиваем «обернутое» значение его примитиву.
После преобразования начального значения в примитив double мы можем преобразовать его в целое число, как показано на рисунке.
Обратите внимание, что это решение поможет вам получить только целую часть любого числа с плавающей запятой. Например, если значение mIHCValue
равно 2.8
или 2.0012
или 2.532
или 2.9999999
, результирующее целое число всегда будет 2
. Итак, будьте осторожны и подумайте о том, чего вы хотите достичь.
Надеюсь, это поможет.
Комментарии:
1. или запретить ввод
"2.3"
, если оно должно быть целым числом; решение действительно зависит от требований проекта. но я согласен; ваше решение лучше 🙂2. @shark Да, точно! Но просто для справки, это решение не просто лучше; операция, которую вы предложили в комментариях, даже не будет компилироваться. Вы не можете назначить a
Float
для anint
.3. @P.Soutzikevich Я попробую это сейчас, однако
"2.3"
вводится для значения FISH (которое является двойным), а не для значения IHC (int). Logcat показывает, что проблема связана со значением IHC, которое может быть только целым значением 0-3.4. @SentientFlesh Если «предполагается» , что это int , то проблема может быть вызвана методом
SharedPrefManager.read()
5. @P.Soutzikevich Хорошо, на данный момент не могу попробовать ваш ответ, но я обновил вопрос с помощью методов SharedPref на случай, если это что-то есть. Надеюсь, это сработает! Спасибо за быструю обратную связь.