货币实用程序 Java 错误代码 'int java.lang.Object.hashCode()'
Currency Util Java error code 'int java.lang.Object.hashCode()'
我正在尝试从 Java Util Currency 显示我的货币对话框,但我在此处的简单试用项目中不断收到此错误,我该如何解决此问题以启动我的对话框,任何帮助都将非常有用赞赏。
这是 GitHub 项目的帮助,我将非常感激。
货币助手Class
class CurrencyHelper {
private static final String[] MAIN_CURRENCIES = {"USD",
"EUR", "GBP", "IRN", "AUD", "CAD", "SGD", "CHF", "MYR", "JPY", "CNY", "NZD","KSH"};
private static final String CURRENCY_ISO = "currency_iso";
private static final DecimalFormat decimalFormatter = new DecimalFormat("#.00");
@NonNull
public static List<Currency> getMainAvailableCurrencies()
{
List<Currency> mainCurrencies = new ArrayList<>(MAIN_CURRENCIES.length);
for(String currencyCode : MAIN_CURRENCIES)
{
try
{
Currency currency = Currency.getInstance(currencyCode);
if( currency != null )
{
mainCurrencies.add(currency);
}
}
catch (Exception e)
{
Logger.getLogger("Unable to find currency with code: "+currencyCode);
}
}
return mainCurrencies;
}
public static List<Currency> getOtherAvailableCurrencies()
{
List<Currency> mainCurrencies = getMainAvailableCurrencies();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
List<Currency> currencies = new ArrayList<>(Currency.getAvailableCurrencies());
// Exclude main currencies
Iterator<Currency> currencyIterator = currencies.iterator();
while (currencyIterator.hasNext())
{
Currency currency = currencyIterator.next();
if( mainCurrencies.contains(currency) )
{
currencyIterator.remove();
}
}
return currencies;
}
else
{
Set<Currency> currencySet = new HashSet<>();
Locale[] locales = Locale.getAvailableLocales();
for(Locale locale : locales)
{
try
{
Currency currency = Currency.getInstance(locale);
if( mainCurrencies.contains(currency) )
{
continue; // Exclude main currencies
}
currencySet.add(currency);
}
catch(Exception ignored)
{
// Locale not found
}
}
List<Currency> currencies = new ArrayList<>(currencySet);
Collections.sort(currencies, new Comparator<Currency>()
{
@Override
public int compare(Currency lhs, Currency rhs)
{
return lhs.getCurrencyCode().compareTo(rhs.getCurrencyCode());
}
});
return currencies;
}
}
代码:
public class Constants {
private final static String SHARED_PREFERENCES_FILE_NAME = "currency_trial";
private final SharedPreferences preferences;
private Constants(@NonNull Context context) {
preferences = context.getApplicationContext().getSharedPreferences(SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
}
public void putInt(@NonNull String key, int value)
{
preferences.edit().putInt(key, value).apply();
}
public void putLong(@NonNull String key, long value)
{
preferences.edit().putLong(key, value).apply();
}
public void putString(@NonNull String key, @NonNull String value)
{
preferences.edit().putString(key, value).apply();
}
public void putBoolean(String key, boolean value)
{
preferences.edit().putBoolean(key, value).apply();
}
public int getInt(@NonNull String key, int defaultValue)
{
return preferences.getInt(key, defaultValue);
}
public long getLong(@NonNull String key, long defaultValue)
{
return preferences.getLong(key, defaultValue);
}
public boolean getBoolean(@NonNull String key, boolean defaultValue) {
return preferences.getBoolean(key, defaultValue);
}
@Nullable
public String getString(String key) {
return preferences.getString(key, null);
}
private static Constants ourInstance;
public static synchronized Constants getInstance(Context context) {
if (ourInstance == null) {
ourInstance = new Constants(context);
}
return ourInstance;
}
}
[1]: https://github.com/annMusenya/Trial-Project
我的异步任务
@SuppressLint("StaticFieldLeak")
private void setupRecyclerView(final View v) {
final RecyclerView recyclerView = v.findViewById(R.id.select_currency_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(v.getContext()));
new AsyncTask<Void, Void, Pair<SelectCurrencyAdapter, Integer>>()
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected Pair<SelectCurrencyAdapter, Integer> doInBackground(Void... voids) {
SelectCurrencyAdapter adapter = new SelectCurrencyAdapter(CurrencyHelper.getMainAvailableCurrencies(),
CurrencyHelper.getOtherAvailableCurrencies());
return Pair.create(adapter, adapter.getSelectedCurrencyPosition(Objects.requireNonNull(getContext())));
}
@Override
protected void onPostExecute(Pair<SelectCurrencyAdapter, Integer> data)
{
recyclerView.setAdapter(data.first);
if( data.second > 1 )
{
recyclerView.scrollToPosition(data.second-1);
}
}
}.execute();
}
完整错误代码:
2018-10-29 10:53:52.204 7840-8080/murray.ann.myapplication E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: murray.ann.myapplication, PID: 7840
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:353)
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 android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
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:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:944)
at java.util.Currency.getInstance(Currency.java:91)
at murray.ann.myapplication.CurrencyHelper.getUserCurrency(CurrencyHelper.java:191)
at murray.ann.myapplication.SelectCurrencyAdapter.getSelectedCurrencyPosition(SelectCurrencyAdapter.java:106)
at murray.ann.myapplication.SelectCurrencyFragment.doInBackground(SelectCurrencyFragment.java:82)
at murray.ann.myapplication.SelectCurrencyFragment.doInBackground(SelectCurrencyFragment.java:76)
at android.os.AsyncTask.call(AsyncTask.java:333)
错误消息有时可能有点令人困惑。实际上错误不在方法 hashCode()
中。实际上它试图在空对象上调用此方法。
在你的例子中,这发生在这个方法中:
static Currency getUserCurrency( Context context) {
return Currency.getInstance(Constants.getInstance(context).getString(CURRENCY_ISO));
}
Constants.getInstance(context).getString(CURRENCY_ISO)
为空。
我正在尝试从 Java Util Currency 显示我的货币对话框,但我在此处的简单试用项目中不断收到此错误,我该如何解决此问题以启动我的对话框,任何帮助都将非常有用赞赏。 这是 GitHub 项目的帮助,我将非常感激。
货币助手Class
class CurrencyHelper {
private static final String[] MAIN_CURRENCIES = {"USD",
"EUR", "GBP", "IRN", "AUD", "CAD", "SGD", "CHF", "MYR", "JPY", "CNY", "NZD","KSH"};
private static final String CURRENCY_ISO = "currency_iso";
private static final DecimalFormat decimalFormatter = new DecimalFormat("#.00");
@NonNull
public static List<Currency> getMainAvailableCurrencies()
{
List<Currency> mainCurrencies = new ArrayList<>(MAIN_CURRENCIES.length);
for(String currencyCode : MAIN_CURRENCIES)
{
try
{
Currency currency = Currency.getInstance(currencyCode);
if( currency != null )
{
mainCurrencies.add(currency);
}
}
catch (Exception e)
{
Logger.getLogger("Unable to find currency with code: "+currencyCode);
}
}
return mainCurrencies;
}
public static List<Currency> getOtherAvailableCurrencies()
{
List<Currency> mainCurrencies = getMainAvailableCurrencies();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
List<Currency> currencies = new ArrayList<>(Currency.getAvailableCurrencies());
// Exclude main currencies
Iterator<Currency> currencyIterator = currencies.iterator();
while (currencyIterator.hasNext())
{
Currency currency = currencyIterator.next();
if( mainCurrencies.contains(currency) )
{
currencyIterator.remove();
}
}
return currencies;
}
else
{
Set<Currency> currencySet = new HashSet<>();
Locale[] locales = Locale.getAvailableLocales();
for(Locale locale : locales)
{
try
{
Currency currency = Currency.getInstance(locale);
if( mainCurrencies.contains(currency) )
{
continue; // Exclude main currencies
}
currencySet.add(currency);
}
catch(Exception ignored)
{
// Locale not found
}
}
List<Currency> currencies = new ArrayList<>(currencySet);
Collections.sort(currencies, new Comparator<Currency>()
{
@Override
public int compare(Currency lhs, Currency rhs)
{
return lhs.getCurrencyCode().compareTo(rhs.getCurrencyCode());
}
});
return currencies;
}
}
代码:
public class Constants {
private final static String SHARED_PREFERENCES_FILE_NAME = "currency_trial";
private final SharedPreferences preferences;
private Constants(@NonNull Context context) {
preferences = context.getApplicationContext().getSharedPreferences(SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
}
public void putInt(@NonNull String key, int value)
{
preferences.edit().putInt(key, value).apply();
}
public void putLong(@NonNull String key, long value)
{
preferences.edit().putLong(key, value).apply();
}
public void putString(@NonNull String key, @NonNull String value)
{
preferences.edit().putString(key, value).apply();
}
public void putBoolean(String key, boolean value)
{
preferences.edit().putBoolean(key, value).apply();
}
public int getInt(@NonNull String key, int defaultValue)
{
return preferences.getInt(key, defaultValue);
}
public long getLong(@NonNull String key, long defaultValue)
{
return preferences.getLong(key, defaultValue);
}
public boolean getBoolean(@NonNull String key, boolean defaultValue) {
return preferences.getBoolean(key, defaultValue);
}
@Nullable
public String getString(String key) {
return preferences.getString(key, null);
}
private static Constants ourInstance;
public static synchronized Constants getInstance(Context context) {
if (ourInstance == null) {
ourInstance = new Constants(context);
}
return ourInstance;
}
}
[1]: https://github.com/annMusenya/Trial-Project
我的异步任务
@SuppressLint("StaticFieldLeak")
private void setupRecyclerView(final View v) {
final RecyclerView recyclerView = v.findViewById(R.id.select_currency_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(v.getContext()));
new AsyncTask<Void, Void, Pair<SelectCurrencyAdapter, Integer>>()
{
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected Pair<SelectCurrencyAdapter, Integer> doInBackground(Void... voids) {
SelectCurrencyAdapter adapter = new SelectCurrencyAdapter(CurrencyHelper.getMainAvailableCurrencies(),
CurrencyHelper.getOtherAvailableCurrencies());
return Pair.create(adapter, adapter.getSelectedCurrencyPosition(Objects.requireNonNull(getContext())));
}
@Override
protected void onPostExecute(Pair<SelectCurrencyAdapter, Integer> data)
{
recyclerView.setAdapter(data.first);
if( data.second > 1 )
{
recyclerView.scrollToPosition(data.second-1);
}
}
}.execute();
}
完整错误代码:
2018-10-29 10:53:52.204 7840-8080/murray.ann.myapplication E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: murray.ann.myapplication, PID: 7840
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:353)
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 android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
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:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:944)
at java.util.Currency.getInstance(Currency.java:91)
at murray.ann.myapplication.CurrencyHelper.getUserCurrency(CurrencyHelper.java:191)
at murray.ann.myapplication.SelectCurrencyAdapter.getSelectedCurrencyPosition(SelectCurrencyAdapter.java:106)
at murray.ann.myapplication.SelectCurrencyFragment.doInBackground(SelectCurrencyFragment.java:82)
at murray.ann.myapplication.SelectCurrencyFragment.doInBackground(SelectCurrencyFragment.java:76)
at android.os.AsyncTask.call(AsyncTask.java:333)
错误消息有时可能有点令人困惑。实际上错误不在方法 hashCode()
中。实际上它试图在空对象上调用此方法。
在你的例子中,这发生在这个方法中:
static Currency getUserCurrency( Context context) {
return Currency.getInstance(Constants.getInstance(context).getString(CURRENCY_ISO));
}
Constants.getInstance(context).getString(CURRENCY_ISO)
为空。