MPAndroidChart饼图开发遇ClassCastException异常求助
解决
java.lang.ClassCastException: Entry cannot be cast to PieEntry问题 嘿,我来帮你搞定这个类型转换异常的问题,咱们一步步来拆解:
核心错误原因
你遇到的这个异常,本质是数据传递方式用错了:MPAndroidChart里的PieEntry类实现的是Parcelable接口,而非Serializable接口。你用putExtra()+getSerializableExtra()来传递ArrayList<PieEntry>,系统在反序列化时会把对象当成Serializable类型处理,再强制转成PieEntry就会触发类型转换错误。
另外还有个隐藏坑:你的DisplayPiechart继承了DisplayDate,这完全没必要!继承后会触发父类的onCreate逻辑(比如再次执行数据库连接),既浪费资源又可能带来其他bug。
具体解决方案
1. 修正Activity间的数据传递方式
把Serializable相关的方法换成Parcelable的对应方法:
- 在
DisplayDate的点击事件里,替换传递数据的代码:
Intent pieIntent = new Intent(DisplayDate.this, DisplayPiechart.class); // 用putParcelableArrayListExtra代替putExtra pieIntent.putParcelableArrayListExtra("Pie Values", yValues); startActivity(pieIntent);
- 在
DisplayPiechart里,用正确的方法接收数据:
ArrayList<PieEntry> myList = getIntent().getParcelableArrayListExtra("Pie Values");
2. 修正DisplayPiechart的继承关系
把它改成继承AppCompatActivity(如果你的项目用AppCompat的话),同时别忘了初始化PieChart控件(你原来的代码里没做这一步,会触发空指针):
class DisplayPiechart extends AppCompatActivity { com.github.mikephil.charting.charts.PieChart pieChart; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.display_piechart); // 初始化PieChart,替换成你布局里的实际ID pieChart = findViewById(R.id.your_piechart_id); Intent i = getIntent(); ArrayList<PieEntry> myList = i.getParcelableArrayListExtra("Pie Values"); // 加个非空判断,避免空指针异常 if(myList != null && !myList.isEmpty()){ PieDataSet dataSet = new PieDataSet(myList, "Stores"); dataSet.setSliceSpace(2f); dataSet.setSelectionShift(6f); dataSet.setColors(ColorTemplate.MATERIAL_COLORS); PieData data = new PieData(dataSet); data.setValueTextSize(10f); data.setValueTextColor(Color.BLACK); pieChart.setData(data); // 必须调用invalidate()刷新图表 pieChart.invalidate(); } } }
3. 修复主线程阻塞问题(重要!)
你原来的doInBackground方法是直接在onCreate里调用的,数据库操作是耗时操作,会阻塞主线程导致ANR(应用无响应)。必须把数据库操作放到子线程里,比如用AsyncTask:
// 在DisplayDate的onCreate里替换原来的doInBackground()调用 new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... voids) { ConnectionHelper connectString = new ConnectionHelper(); connect = connectString.connectionClass(); Log.w("Android","Connecting...."); if (connect == null) { Log.w("Android","Connection Failed"); ConnectionResult = "Check Your Internet Connection"; } else { Log.w("Android","Connected"); String query = "Select No_,Name,Date,[Net Amount],[Gross Amount] from [CRONUS LS 1010 W1 Demo$Store] as str,[CRONUS LS 1010 W1 Demo$Transaction Header] as trans where str.[No_] = trans.[Store No_] and trans.[Date] between '"+Actual_Start+"' and '"+Actual_End+"' "; try { Statement stmt = connect.createStatement(); ResultSet rs = stmt.executeQuery(query); Log.w("Android","database Connected"); while (rs.next()) { final String no = rs.getString("No_"); final String name = rs.getString("Name"); final String date = rs.getString("Date"); final String netAmount = rs.getString("Net Amount"); final String grossAmount = rs.getString("Gross Amount"); final float gross = Float.parseFloat(grossAmount); // 更新UI必须在主线程,所以用runOnUiThread runOnUiThread(() -> { TR = new TableRow(DisplayDate.this); TV1.setText(no); TV2.setText(name); TV4.setText(date); TV5.setText(netAmount); TV3.setText(grossAmount); TL.addView(TR); }); yValues.add(new PieEntry(gross, no)); } ConnectionResult = "Successful"; isSuccess = true; connect.close(); } catch (SQLException e) { e.printStackTrace(); } } return null; } }.execute();
内容的提问来源于stack exchange,提问作者Shubham Mundra
相关产品推荐
相关产品推荐

