Я форматирую BigDecimal с использованием класса DecimalFormat, но у меня много отчетов о сбоях.Я не могу воспроизвести эту проблему самостоятельно, однако я знаю, что DecimalFormat не является потокобезопасным , и я, вероятно, где-то допустил ошибку.
Я просто не знаю, что может быть причиной этой проблемы, потому что я уверен, что BigDecimal не равен NULL, и я каждый раз создаю новый экземпляр DecimalFormat.Есть что-то, что я упустил?
Единственное, что я могу придумать, - это синхронизировать метод.Но я не уверен, что это поможет, и я бы предпочел не использовать его, так как это замедлит процесс.
Это один из сбоев:
java.lang.RuntimeException:
at java.lang.reflect.Constructor.newInstance0 (Constructor.java)
at java.lang.reflect.Constructor.newInstance (Constructor.java:343)
at androidx.loader.content.ModernAsyncTask$3.done (ModernAsyncTask.java:164)
at java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:383)
at java.util.concurrent.FutureTask.setException (FutureTask.java:252)
at java.util.concurrent.FutureTask.run (FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
at java.lang.Thread.run (Thread.java:764)
Caused by: java.lang.NullPointerException:
at java.math.BigInt.putLittleEndianInts (BigInt.java:175)
at java.math.BigInteger.getBigInt (BigInteger.java:322)
at java.math.BigInteger.toString (BigInteger.java:856)
at java.math.BigDecimal.toString (BigDecimal.java:2204)
at android.icu.text.DigitList_Android.set (DigitList_Android.java:724)
at android.icu.text.DecimalFormat_ICU58_Android.format (DecimalFormat_ICU58_Android.java:1202)
at android.icu.text.DecimalFormat_ICU58_Android.format (DecimalFormat_ICU58_Android.java:1187)
at java.text.DecimalFormat.format (DecimalFormat.java:709)
at java.text.DecimalFormat.format (DecimalFormat.java:634)
at java.text.Format.format (Format.java:157)
at com.myapp.formatter.Format.formatAmount (Format.java:230)
at com.myapp.formatter.MyContentProvider.query (MyContentProvider.java:123)
at android.content.ContentProvider.query (ContentProvider.java:1057)
at android.content.ContentProvider.query (ContentProvider.java:1149)
at android.content.ContentProvider$Transport.query (ContentProvider.java:241)
at android.content.ContentResolver.query (ContentResolver.java:802)
at android.content.ContentResolver.query (ContentResolver.java:752)
at androidx.core.content.ContentResolverCompat.query (ContentResolverCompat.java:81)
at androidx.loader.content.CursorLoader.loadInBackground (CursorLoader.java:63)
at androidx.loader.content.CursorLoader.loadInBackground (CursorLoader.java:41)
at androidx.loader.content.AsyncTaskLoader.onLoadInBackground (AsyncTaskLoader.java:307)
at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground$532ebdd5 (AsyncTaskLoader.java:60)
at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground$42af7916 (AsyncTaskLoader.java:48)
at androidx.loader.content.ModernAsyncTask$2.call (ModernAsyncTask.java:141)
at java.util.concurrent.FutureTask.run (FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
at java.lang.Thread.run (Thread.java:764)
И этокод:
public static String formatAmount(BigDecimal bigDecimal, boolean includeCents, boolean includeCurrency)
{
String formattedAmount = "";
if (bigDecimal != null)
{
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(getLocale());
DecimalFormat decimalFormat;
if (includeCurrency)
{
decimalFormat = new DecimalFormat("¤\u00A0#,##0.00;¤\u00A0-#,##0.00", decimalFormatSymbols);
}
else
{
decimalFormat = new DecimalFormat("#,##0.00;-#,##0.00", decimalFormatSymbols);
}
int fractionDigits = includeCents ? 2 : 0;
bigDecimal.setScale(fractionDigits, BigDecimal.ROUND_DOWN);
decimalFormat.setMinimumFractionDigits(fractionDigits);
decimalFormat.setMaximumFractionDigits(fractionDigits);
// exception happens on next line.
formattedAmount = decimalFormat.format(bigDecimal);
}
return formattedAmount;
}
Редактировать: Я не знаю, почему мой вопрос помечен как дубликат.Дело не в том, что я не знаю, что такое NullPointer или как его исправить.Прежде всего я уверен, что мои переменные и параметры не равны нулю.Отладка или ведение журнала не вариант, потому что я не могу воспроизвести эту проблему.И, наконец, NullPointer даже не вызван моим кодом.Так что я думаю, что это действительно уникальная ситуация, которую я не могу исправить самостоятельно.
Я также натолкнулся на код Android , на котором отображается нулевой указатель.И я думаю, что стоит упомянуть, что большинство сбоев происходит на устройствах Huawei.Еще одно отличие, которое я обнаружил, заключается в том, что для некоторых версий Android трассировка стека отличается.Первая трассировка стека была для устройств с Android 9. И это трассировка стека в более низких версиях Android (7, 8.0 и 8.1):
java.lang.RuntimeException:
at java.lang.reflect.Constructor.newInstance0 (Constructor.java)
at java.lang.reflect.Constructor.newInstance (Constructor.java:334)
at androidx.loader.content.ModernAsyncTask$3.done (ModernAsyncTask.java:164)
at java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:383)
at java.util.concurrent.FutureTask.setException (FutureTask.java:252)
at java.util.concurrent.FutureTask.run (FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:636)
at java.lang.Thread.run (Thread.java:784)
Caused by: java.lang.NullPointerException:
at java.math.BigInt.putLittleEndianInts (BigInt.java:173)
at java.math.BigInteger.getBigInt (BigInteger.java:322)
at java.math.BigInteger.toString (BigInteger.java:856)
at java.math.BigDecimal.toString (BigDecimal.java:2204)
at android.icu.text.DigitList.set (DigitList.java:721)
at android.icu.text.DecimalFormat.format (DecimalFormat.java:1187)
at android.icu.text.DecimalFormat.format (DecimalFormat.java:1172)
at java.text.DecimalFormat.format (DecimalFormat.java:658)
at java.text.DecimalFormat.format (DecimalFormat.java:592)
at java.text.Format.format (Format.java:157)
at com.myapp.formatter.Format.formatAmount (Format.java:230)
at com.myapp.formatter.MyContentProvider.query (MyContentProvider.java:123)
at android.content.ContentProvider.query (ContentProvider.java:1059)
at android.content.ContentProvider.query (ContentProvider.java:1151)
at android.content.ContentProvider$Transport.query (ContentProvider.java:243)
at android.content.ContentResolver.query (ContentResolver.java:766)
at android.content.ContentResolver.query (ContentResolver.java:716)
at androidx.core.content.ContentResolverCompat.query (ContentResolverCompat.java:81)
at androidx.loader.content.CursorLoader.loadInBackground (CursorLoader.java:63)
at androidx.loader.content.CursorLoader.loadInBackground (CursorLoader.java:41)
at androidx.loader.content.AsyncTaskLoader.onLoadInBackground (AsyncTaskLoader.java:307)
at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground$532ebdd5 (AsyncTaskLoader.java:60)
at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground$42af7916 (AsyncTaskLoader.java:48)
at androidx.loader.content.ModernAsyncTask$2.call (ModernAsyncTask.java:141)
at java.util.concurrent.FutureTask.run (FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:636)
at java.lang.Thread.run (Thread.java:784)