如何防止 java.lang.nullpointerexception 将用户输入添加到 MPandroidchart

How to prevent java.lang.nullpointerexception on adding user input to MPandroidchart

我使用 MPandroidchart 在 android studio 的片段中创建了一个折线图,并使图表的点来自用户输入。但是,我收到错误 'java.lang.NullPointerException'。我知道此错误是由于尝试使用 null 值引起的,但我不确定在我的情况下如何修复它。

编辑:用户输入保存在房间数据库中

我从一个方法中检索用户输入,其中有代码确保输入为空时不保存。我认为问题是因为图表试图在用户添加数据之前构建,因为输入选项是显示图表的片段的一部分,所以图表试图在数据准备好之前构建。

Graph.java

public class Graph extends Fragment {

    public Graph() {
        // Required empty public constructor
    }
    private LineChart mChart;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_graph, container, false);
        //initialize input1 database
        InputRoomDatabase db = Room.databaseBuilder(getActivity(),InputRoomDatabase.class, "input_database")
                .build();
        //initialize chart
        mChart = view.findViewById(R.id.chart);
        //set description
        Description description = new Description();
        description.setText("Blood glucose levels");
        mChart.setDescription(description);
            //set description if no data is available
        mChart.setNoDataText("No Data Available. Add a blood glucose level input to see your graph");
        //enable touch gestures
        mChart.setTouchEnabled(true);
        //enable scaling and dragging
        mChart.setDragEnabled(true);
        mChart.setScaleEnabled(true);
        //draw background grid
        mChart.setDrawGridBackground(true);
        //draw x-axis
        XAxis xAxis = mChart.getXAxis();
        xAxis.setEnabled(false);
        // setting position to TOP and INSIDE the chart
        xAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
        //  setting text size for our axis label
        xAxis.setTextSize(10f);
        xAxis.setTextColor(Color.BLACK);
        // to draw axis line
        xAxis.setDrawAxisLine(true);
        xAxis.setDrawGridLines(false);

        YAxis yAxis = mChart.getAxisLeft();
        // setting the count of Y-axis label's
        yAxis.setLabelCount(12, false);
        yAxis.setTextColor(Color.BLACK);
        yAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        yAxis.setDrawGridLines(true);

        mChart.getAxisRight().setEnabled(false);
        // add data
        setData();
        mChart.getLegend().setEnabled(false);
        // refresh the chart

        mChart.notifyDataSetChanged();
        mChart.invalidate();


        return view;
    }

    private void setData(){
        ArrayList<Entry> values = new ArrayList<>();
**
        Double d = getActivity().getIntent().getExtras().getDouble("STRING_I_NEED");
**
        float myDataSet = d.floatValue();

        values.add(new Entry(1,myDataSet));

        LineDataSet set1;
        if (mChart.getData() != null &&
                mChart.getData().getDataSetCount() > 0) {
            set1 = (LineDataSet) mChart.getData().getDataSetByIndex(0);
            set1.setValues(values);
            mChart.getData().notifyDataChanged();
            mChart.notifyDataSetChanged();
        } else {
            set1 = new LineDataSet(values, "Blood Glucose Levels");
            set1.setDrawIcons(false);
            set1.setLineWidth(2f);
            set1.setCircleRadius(3f);
            set1.setDrawCircleHole(false);
            set1.setValueTextSize(9f);
            set1.setFormLineWidth(1f);
            set1.setFormSize(15.f);
            set1.setColor(Color.BLACK);
            set1.setCircleColor(Color.BLACK);

        }
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(set1);
        LineData data = new LineData(dataSets);
        mChart.setData(data);

    }
}

Tabbed.java(片段的基础 class)(仅相关代码)

 //getting inputs from room and putting them into the view in table
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        mInputViewModel = ViewModelProviders.of(this).get(InputViewModel.class);
        //only add if there is a new input
        if (requestCode == INPUT_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
            //retrieve input from room database
            Input1 input1 = new Input1(data.getStringExtra(input.EXTRA_REPLY));
            //insert the inputs into the view model of the recyclerView
            mInputViewModel.insert(input1);
            //convert the String input1 to a double
            Double d = Double.parseDouble(input1.getValue());
            //display pop-up if blood is above target
            if (d > 8.0) {
                Toast.makeText(
                        getApplicationContext(),
                        R.string.PopupHigh,
                        Toast.LENGTH_LONG).show();
            }
            //display pop-up if blood is below target
            if (d < 4.0) {
                Toast.makeText(
                        getApplicationContext(),
                        R.string.PopupLow,
                        Toast.LENGTH_LONG).show();
            }
            Intent i = new Intent(Tabbed.this, Graph.class);
            i.putExtra("STRING_I_NEED", d);
            //display pop-up if no input is added don't save the input
        } else {
            Toast.makeText(
                    getApplicationContext(),
                    R.string.empty_not_saved,
                    Toast.LENGTH_LONG).show();
        }
    }
        public static final int INPUT_ACTIVITY_REQUEST_CODE = 1;

}

当我 运行 应用程序时,它崩溃并出现此错误 java.lang.NullPointerException: Attempt to invoke virtual method 'double android.os.Bundle.getDouble(java.lang.String)' on a null object reference 我在 Graph.java 中用 **

标记了问题代码

正如我所说,我认为问题是图表在数据准备好之前试图构建,但我不确定如何避免这个问题。

感谢您的帮助!

代码:

Double d = getActivity().getIntent().getExtras().getDouble("STRING_I_NEED");
float myDataSet = d.floatValue();

假设 4 个方法调用所有 return 非空值。请参阅库方法的文档,了解它们何时可能 return null,以及通常如何避免不愉快的意外。

文档说 getExtras() returns

the map of all extras previously added with putExtra(), or null if none have been added.

当调用可以 return null 的库方法时,您的代码应检查 null 结果(或捕获 NullPointerException),或确保情况不可能发生,或两者都发生。

  • 因为Intents来自系统的其余部分,你不能保证它们总是有额外的,所以代码需要测试getExtras()的结果是否是null 在调用 getDouble() 之前优雅地处理它。
  • 您还需要调试为什么这个 Intent 没有您期望的额外内容。
  • 如果 Intent 有 extras 但这些 extras 没有名为 "STRING_I_NEED" 的双精度值,那么 getDouble("STRING_I_NEED") 将 return 0.0。您可能需要将显式 defaultValue 传递给 getDouble() 或测试 Bundle containsKey("STRING_I_NEED").
  • 如果您想要一个浮点值,请考虑调用 getFloat() 而不是 getDouble()。我 认为 可以将双精度值转换为浮点数。