因此,我的应用程序已发布在Play商店中,似乎我的一些用户正在崩溃。我正在尝试重现它以获取日志,但不能完全束缚Google提供的错误日志。
但是,老实说,我无法从日志中了解此问题,因此需要您的帮助!
崩溃日志
java.lang.IllegalStateException:
at android.support.v4.app.Fragment.requireContext (Fragment.java:614)
at android.support.v4.app.Fragment.getResources (Fragment.java:678)
at com.tinyapps.newsly.providers.priceticker.currencydetails.chartandtable.GraphFragment.lambda$getCMCChart$0$GraphFragment (GraphFragment.java:243)
at com.tinyapps.newsly.providers.priceticker.currencydetails.chartandtable.GraphFragment$$Lambda$0.onTaskCompleted (Unknown Source:8)
at com.grizzly.rest.GenericRestCall.afterCall (GenericRestCall.java:1054)
at com.grizzly.rest.GenericRestCall.onPostExecute (GenericRestCall.java:1030)
at com.grizzly.rest.GenericRestCall.onPostExecute (GenericRestCall.java:55)
at android.os.AsyncTask.finish (AsyncTask.java:695)
at android.os.AsyncTask.-wrap1 (Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:712)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:164)
at android.app.ActivityThread.main (ActivityThread.java:6753)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:482)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
此片段的代码
public class GraphFragment extends Fragment implements OnChartValueSelectedListener {
private int chartFillColor;
private int chartBorderColor;
private String cryptoID;
private int percentageColor;
private LineChart lineChart;
private View rootView;
private CustomViewPager viewPager;
private IAxisValueFormatter XAxisFormatter;
public final IAxisValueFormatter monthSlashDayXAxisFormatter = new MonthSlashDayDateFormatter();
public final TimeDateFormatter dayCommaTimeDateFormatter = new TimeDateFormatter();
public final MonthSlashYearFormatter monthSlashYearFormatter = new MonthSlashYearFormatter();
private String currentTimeWindow = "";
private SingleSelectToggleGroup buttonGroup;
public static String CURRENT_CHART_URL;
public final static DecimalFormat rawNumberFormat = new DecimalFormat("#,###.##");
private LockableNestedScrollView nestedScrollView;
private int displayWidth;
private ProgressBar chartProgressBar;
private String tsymbol;
private CurrencyFormatterSingleton currencyFormatter;
private SharedPreferences sharedPreferences;
NumberFormat chartUSDPriceFormat = NumberFormat.getInstance();
SimpleDateFormat fullDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.ENGLISH);
public static final String SHAREDPREF_SETTINGS = "newsly_settings";
public static final String CHART_SPINNER_SETTING = "chart_spinner_setting";
public static final String ARG_SYMBOL = "symbol";
public static final String ARG_ID = "ID";
public static final String COIN_OBJECT = "COIN_OBJECT";
public GraphFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static GraphFragment newInstance(String symbol, String id) {
GraphFragment fragment = new GraphFragment();
Bundle args = new Bundle();
args.putString(ARG_SYMBOL, symbol);
args.putString(ARG_ID, id);
fragment.setArguments(args);
return fragment;
}
public void setColors(float percentChange) {
if (percentChange >= 0) {
chartFillColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.materialLightGreen, null);
chartBorderColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.darkGreen, null);
percentageColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.percentPositiveGreen, null);
}
else {
chartFillColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.materialLightRed, null);
chartBorderColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.darkRed, null);
percentageColor = ResourcesCompat.getColor(getActivity().getResources(), R.color.percentNegativeRed, null);
}
}
public void setUpChart() {
XAxis xAxis = lineChart.getXAxis();
xAxis.setDrawAxisLine(false);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM_INSIDE);
xAxis.setAvoidFirstLastClipping(false);
lineChart.getAxisLeft().setEnabled(true);
lineChart.getAxisLeft().setDrawGridLines(true);
lineChart.getAxisLeft().setTextColor(Color.WHITE);
lineChart.getXAxis().setTextColor(Color.WHITE);
lineChart.getXAxis().setDrawGridLines(true);
lineChart.getAxisRight().setEnabled(false);
lineChart.getLegend().setTextColor(Color.WHITE);
lineChart.getLegend().setEnabled(false);
lineChart.setDoubleTapToZoomEnabled(false);
lineChart.setScaleEnabled(false);
lineChart.getDescription().setEnabled(false);
lineChart.setContentDescription("");
lineChart.setNoDataText(getString(R.string.noChartDataString));
lineChart.setNoDataTextColor(R.color.darkRed);
lineChart.setOnChartValueSelectedListener(this);
lineChart.setOnChartGestureListener(new OnChartGestureListener() {
@Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
YAxis yAxis = lineChart.getAxisLeft();
// Allow scrolling in the right and left margins
if (me.getX() > yAxis.getLongestLabel().length() * yAxis.getTextSize() &&
me.getX() < displayWidth - lineChart.getViewPortHandler().offsetRight()) {
viewPager.setPagingEnabled(false);
nestedScrollView.setScrollingEnabled(false);
}
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
viewPager.setPagingEnabled(true);
nestedScrollView.setScrollingEnabled(true);
}
@Override
public void onChartLongPressed(MotionEvent me) {
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
}
@Override
public void onChartSingleTapped(MotionEvent me) {
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
}
});
}
public LineDataSet setUpLineDataSet(List<Entry> entries) {
LineDataSet dataSet = new LineDataSet(entries, "Price");
dataSet.setColor(chartBorderColor);
dataSet.setFillColor(chartFillColor);
dataSet.setDrawFilled(true);
dataSet.setDrawCircles(false);
dataSet.setCircleColor(chartBorderColor);
dataSet.setDrawCircleHole(false);
dataSet.setDrawValues(true);
dataSet.setValueTextColor(getResources().getColor(R.color.white));
dataSet.setHighLightColor(getResources().getColor(R.color.white));
dataSet.setCircleRadius(1);
dataSet.setHighlightLineWidth(2);
dataSet.setHighlightEnabled(false);
dataSet.setDrawHighlightIndicators(false);
dataSet.setHighLightColor(chartBorderColor); // color for highlight indicator
return dataSet;
}
public void getCMCChart() {
final TextView percentChangeText = rootView.findViewById(R.id.percent_change);
final TextView currPriceText = rootView.findViewById(R.id.current_price);
currPriceText.setTextColor(getResources().getColor(R.color.white));
lineChart.setEnabled(true);
lineChart.clear();
chartProgressBar.setVisibility(View.VISIBLE);
CoinMarketCapService.getCMCChartData(getActivity(), cryptoID, cmcChartData -> {
List<Entry> closePrices = new ArrayList<>();
if (tsymbol.equals("USD")) {
for (List<Float> priceTimeUnit : cmcChartData.getPriceUSD()) {
closePrices.add(new Entry(priceTimeUnit.get(0), priceTimeUnit.get(1)));
}
} else {
for (List<Float> priceTimeUnit : cmcChartData.getPriceBTC()) {
closePrices.add(new Entry(priceTimeUnit.get(0), priceTimeUnit.get(1)));
}
}
if (closePrices.size() == 0) {
lineChart.setData(null);
lineChart.setEnabled(false);
lineChart.invalidate();
percentChangeText.setText("");
currPriceText.setText("");
lineChart.setNoDataText(getResources().getString(R.string.noChartDataString));
chartProgressBar.setVisibility(View.GONE);
return;
}
XAxis xAxis = lineChart.getXAxis();
xAxis.setValueFormatter(XAxisFormatter);
// TextView currentPriceTextView = rootView.findViewById(R.id.current_price);
float currPrice = closePrices.get(closePrices.size() - 1).getY();
TextView chartDateTextView = rootView.findViewById(R.id.graphFragmentDateTextView);
chartDateTextView.setText(getFormattedFullDate(closePrices.get(closePrices.size() - 1).getX()));
if (tsymbol.equals("USD")) {
currPriceText.setText(String.format(getResources().getString(R.string.unrounded_usd_chart_price_format), String.valueOf(currPrice)));
} else {
currPriceText.setText(currencyFormatter.format(currPrice, "BTC"));
}
currPriceText.setTextColor(Color.WHITE);
float firstPrice = closePrices.get(0).getY();
// Handle edge case where we dont have data for the interval on the chart. E.g. user selects
// 3 month window, but we only have data for last month
for (Entry e: closePrices) {
if (firstPrice != 0) {
break;
} else {
firstPrice = e.getY();
}
}
float difference = (currPrice - firstPrice);
float percentChange = (difference / firstPrice) * 100;
if (percentChange < 0) {
if (tsymbol.equals("USD")) {
percentChangeText.setText(String.format(getResources().getString(R.string.negative_variable_pct_change_with_dollars_format), currentTimeWindow, percentChange, Math.abs(difference)));
} else {
percentChangeText.setText(String.format(getResources().getString(R.string.negative_variable_pct_change_without_dollars_format), currentTimeWindow, percentChange));
}
} else {
if (tsymbol.equals("USD")) {
percentChangeText.setText(String.format(getResources().getString(R.string.positive_variable_pct_change_with_dollars_format), currentTimeWindow, percentChange, Math.abs(difference)));
} else {
percentChangeText.setText(String.format(getResources().getString(R.string.positive_variable_pct_change_without_dollars_format), currentTimeWindow, percentChange));
}
}
setColors(percentChange);
percentChangeText.setTextColor(percentageColor);
LineDataSet dataSet = setUpLineDataSet(closePrices);
LineData lineData = new LineData(dataSet);
lineChart.setData(lineData);
lineChart.animateX(800);
chartProgressBar.setVisibility(View.GONE);
}, new afterTaskFailure() {
@Override
public void onTaskFailed(Object o, Exception e) {
Log.e("ERROR", "Server Error: " + e.getMessage());
lineChart.setNoDataText(getString(R.string.noChartDataString));
chartProgressBar.setVisibility(View.GONE);
}
}, true);
}
public void setDayChecked(Calendar cal) {
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();
cal.clear();
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_WINDOW, cryptoID, startTime, endTime);
currentTimeWindow = getString(R.string.oneDay);
XAxisFormatter = dayCommaTimeDateFormatter;
}
public void setWeekChecked(Calendar cal) {
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -7);
long startTime = cal.getTimeInMillis();
cal.clear();
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_WINDOW, cryptoID, startTime, endTime);
currentTimeWindow = getString(R.string.Week);
XAxisFormatter = monthSlashDayXAxisFormatter;
}
public void setMonthChecked(Calendar cal) {
long endTime = cal.getTimeInMillis();
cal.add(Calendar.MONTH, -1);
long startTime = cal.getTimeInMillis();
cal.clear();
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_WINDOW, cryptoID, startTime, endTime);
currentTimeWindow = getString(R.string.Month);
XAxisFormatter = monthSlashDayXAxisFormatter;
}
public void setThreeMonthChecked(Calendar cal) {
long endTime = cal.getTimeInMillis();
cal.add(Calendar.MONTH, -3);
long startTime = cal.getTimeInMillis();
cal.clear();
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_WINDOW, cryptoID, startTime, endTime);
currentTimeWindow = getString(R.string.threeMonth);
XAxisFormatter = monthSlashDayXAxisFormatter;
}
public void setYearChecked(Calendar cal) {
long endTime = cal.getTimeInMillis();
cal.add(Calendar.YEAR, -1);
long startTime = cal.getTimeInMillis();
cal.clear();
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_WINDOW, cryptoID, startTime, endTime);
currentTimeWindow = getString(R.string.Year);
XAxisFormatter = monthSlashYearFormatter;
}
public void setAllTimeChecked() {
currentTimeWindow = getString(R.string.AllTime);
CURRENT_CHART_URL = String.format(COIN_MARKETCAP_CHART_URL_ALL_DATA, cryptoID);
XAxisFormatter = monthSlashYearFormatter;
}
public void setTable(CMCCoin coinObject, View rootVeiw) {
String usdFormat = getString(R.string.usd_format);
String negativePctFormat = getString(R.string.negative_pct_format);
String positivePctFormat = getString(R.string.positive_pct_format);
int negativeRedColor = getResources().getColor(R.color.percentNegativeRed);
int positiveGreenColor = getResources().getColor(R.color.percentPositiveGreen);
TextView nameTextView = rootVeiw.findViewById(R.id.tableNameDataTextView);
if (coinObject.getName() == null) {
nameTextView.setText("N/A");
} else {
nameTextView.setText(coinObject.getName());
}
TextView priceUSDTextView = rootVeiw.findViewById(R.id.tablePriceUSDDataTextView);
if (coinObject.getPrice_usd() == null) {
priceUSDTextView.setText("N/A");
} else {
priceUSDTextView.setText(String.format(usdFormat, Double.parseDouble(coinObject.getPrice_usd())));
}
TextView priceBTCTextView = rootVeiw.findViewById(R.id.tablePriceBTCDataTextView);
if (coinObject.getPrice_btc() == null) {
priceBTCTextView.setText("N/A");
} else {
priceBTCTextView.setText(String.format(getString(R.string.btc_format), coinObject.getPrice_btc()));
}
TextView volumeTextView = rootVeiw.findViewById(R.id.tableVolUSDDataTextView);
if (coinObject.getVolume_usd_24h() == null) {
volumeTextView.setText("N/A");
} else {
volumeTextView.setText(String.format(usdFormat, Double.parseDouble(coinObject.getVolume_usd_24h())));
}
TextView mktCapTextView = rootVeiw.findViewById(R.id.tableMktCapDataTextView);
if (coinObject.getMarket_cap_usd() == null) {
mktCapTextView.setText("N/A");
} else {
mktCapTextView.setText(String.format(usdFormat, Double.parseDouble(coinObject.getMarket_cap_usd())));
}
TextView availSupplyTextView = rootVeiw.findViewById(R.id.tableAvailableSupplyDataTextView);
if (coinObject.getAvailable_supply() == null) {
availSupplyTextView.setText("N/A");
} else {
availSupplyTextView.setText(rawNumberFormat.format(Double.parseDouble(coinObject.getAvailable_supply())));
}
TextView totalSupplyTextView = rootVeiw.findViewById(R.id.tableTotalSupplyDataTextView);
if (coinObject.getTotal_supply() == null) {
totalSupplyTextView.setText("N/A");
} else {
totalSupplyTextView.setText(rawNumberFormat.format(Double.parseDouble(coinObject.getTotal_supply())));
}
TextView maxSupplyTextView = rootVeiw.findViewById(R.id.tableMaxSupplyDataTextView);
if (coinObject.getMax_supply() == null) {
maxSupplyTextView.setText("N/A");
} else {
maxSupplyTextView.setText(rawNumberFormat.format(Double.parseDouble(coinObject.getMax_supply())));
}
TextView oneHrChangeTextView = rootVeiw.findViewById(R.id.table1hrChangeDataTextView);
if (coinObject.getPercent_change_1h() == null) {
oneHrChangeTextView.setText("N/A");
} else {
double amount = Double.parseDouble(coinObject.getPercent_change_1h());
if (amount >= 0) {
oneHrChangeTextView.setText("Change 1h\n" +String.format(positivePctFormat, amount));
oneHrChangeTextView.setTextColor(positiveGreenColor);
} else {
oneHrChangeTextView.setText("Change 1h\n" +String.format(negativePctFormat, amount));
oneHrChangeTextView.setTextColor(negativeRedColor);
}
}
TextView dayChangeTextView = rootVeiw.findViewById(R.id.table24hrChangeDataTextView);
if (coinObject.getPercent_change_24h() == null) {
dayChangeTextView.setText("N/A");
} else {
double amount = Double.parseDouble(coinObject.getPercent_change_24h());
if (amount >= 0) {
dayChangeTextView.setText("Change 24h\n" +String.format(positivePctFormat, amount));
dayChangeTextView.setTextColor(positiveGreenColor);
} else {
dayChangeTextView.setText("Change 24h\n" +String.format(negativePctFormat, amount));
dayChangeTextView.setTextColor(negativeRedColor);
}
}
TextView weekChangeTextView = rootVeiw.findViewById(R.id.tableWeekChangeDataTextView);
if (coinObject.getPercent_change_7d() == null) {
weekChangeTextView.setText("N/A");
} else {
double amount = Double.parseDouble(coinObject.getPercent_change_7d());
if (amount >= 0) {
weekChangeTextView.setText("Change 7d\n" +String.format(positivePctFormat, amount));
weekChangeTextView.setTextColor(positiveGreenColor);
} else {
weekChangeTextView.setText("Change 7d\n" +String.format(negativePctFormat, amount));
weekChangeTextView.setTextColor(negativeRedColor);
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_graph, container, false);
lineChart = rootView.findViewById(R.id.chart);
chartUSDPriceFormat = NumberFormat.getInstance();
chartUSDPriceFormat.setMaximumFractionDigits(10);
setUpChart();
currencyFormatter = CurrencyFormatterSingleton.getInstance(getContext());
// WindowManager mWinMgr = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
// displayWidth = mWinMgr.getDefaultDisplay().getWidth();
chartProgressBar = rootView.findViewById(R.id.chartProgressSpinner);
// Button sourceButton = rootView.findViewById(R.id.sourceButton);
// sourceButton.setPaintFlags(sourceButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
sharedPreferences = getContext().getSharedPreferences(SHAREDPREF_SETTINGS, MODE_PRIVATE);
Spinner chartCurrencySelector = rootView.findViewById(R.id.chartCurrencySelectSpinnr);
final ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_item, getResources().getStringArray(R.array.chart_spinner_options));
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
tsymbol = sharedPreferences.getString(CHART_SPINNER_SETTING, "USD");
chartCurrencySelector.setAdapter(spinnerArrayAdapter);
if (tsymbol.equals("USD")) {
chartCurrencySelector.setSelection(0);
} else {
chartCurrencySelector.setSelection(1);
}
chartCurrencySelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// ((TextView) chartCurrencySelector.getSelectedView()).setTextColor(Color.WHITE);
tsymbol = spinnerArrayAdapter.getItem(position);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(CHART_SPINNER_SETTING, tsymbol);
editor.apply();
getCMCChart();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
viewPager = (CustomViewPager) container;
nestedScrollView = rootView.findViewById(R.id.graphFragmentNestedScrollView);
buttonGroup = rootView.findViewById(R.id.chart_interval_button_grp);
cryptoID = getArguments().getString(ARG_ID);
setDayChecked(Calendar.getInstance());
buttonGroup.check(R.id.dayButton);
currentTimeWindow = getString(R.string.oneDay);
// sourceButton.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
// CustomTabsIntent customTabsIntent = builder.build();
// customTabsIntent.launchUrl(getActivity(), Uri.parse(BASE_CMC_SOURCE_URL + cryptoID));
// }
// });
buttonGroup.setOnCheckedChangeListener((group, checkedId) -> {
Calendar.getInstance();
switch (checkedId) {
case R.id.dayButton:
setDayChecked(Calendar.getInstance());
getCMCChart();
break;
case R.id.weekButton:
setWeekChecked(Calendar.getInstance());
getCMCChart();
break;
case R.id.monthButton:
setMonthChecked(Calendar.getInstance());
getCMCChart();
break;
case R.id.threeMonthButton:
setThreeMonthChecked(Calendar.getInstance());
getCMCChart();
break;
case R.id.yearButton:
setYearChecked(Calendar.getInstance());
getCMCChart();
break;
case R.id.allTimeButton:
setAllTimeChecked();
getCMCChart();
break;
}
});
CMCCoin coinObject = getActivity().getIntent().getParcelableExtra(GraphFragment.COIN_OBJECT);
setTable(coinObject, rootView);
return rootView;
}
// test commit
@Override
public void onValueSelected(Entry e, Highlight h) {
TextView currentPrice = rootView.findViewById(R.id.current_price);
currentPrice.setTextColor(getResources().getColor(R.color.myTextPrimaryColor));
TextView dateTextView = rootView.findViewById(R.id.graphFragmentDateTextView);
if (tsymbol.equals("USD")) {
currentPrice.setText(String.format(getString(R.string.unrounded_usd_chart_price_format), String.valueOf(e.getY())));
} else {
currentPrice.setText(currencyFormatter.format(e.getY(), "BTC"));
}
dateTextView.setText(getFormattedFullDate(e.getX()));
}
@Override
public void onNothingSelected() {
}
public String getFormattedFullDate(float unixSeconds) {
Date date = new Date((long)unixSeconds);
return fullDateFormat.format(date);
}
}
谢谢,期待获得帮助!
编辑:根据文档,重复代码时会发生 IllegalStateException 错误,至少这是我的理解,但是我的代码没有重复。
答案 0 :(得分:1)
通常,IllegalStateException用于指示“方法已在非法或不适当的时间被调用”。但是,这看起来并不特别典型。
https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/IllegalStateException.html
非法状态异常是未经检查的异常。它表明该方法在错误的时间被调用。
示例:
Thread t = new Thread();
t.start();
//
//
t.start();
我们无法再次启动线程,它将引发IllegalStateException。
答案 1 :(得分:1)
可以避免...
bool imagestring ( resource $image , int $font , int $x , int $y , string $string , int $color )
public void getCMCChart() {
if(getActivity() != null) {
...
}
}
假定getResources()
附加到Fragment
的实例-当在{的非法状态下调用该方法时,将导致Context
{1}}。也可以使用IllegalStateException
或!isAttached()
进行检查。