片段内的空指针异常

时间:2016-08-09 17:41:19

标签: android android-fragments nullpointerexception mpandroidchart

我正在尝试根据其余调用返回的输入更新View,它代表graph(MpAndroidChart=library, class=BarChart),位于Fragment内。我尝试使用名为updateGraph()的方法更新View,并且我得到一个空指针异常 我的updateGraph()方法的代码如下。

对此的任何帮助将不胜感激。

有关如何调用此方法的一般说明如下:我的MainActivity创建了一个runnable,它在我创建并用作字段的updateGraph()实例上调用FragmentOne在我的Activity 然后我将该runnable传递给我的RestCall(AsyncTask),以避免传递活动本身 当返回来自其余调用的信息时,我将其保存为单例并引用它,类似于您在SharedPreferences中的操作,以更新图形。
下面的代码使用预定义的值来更新图表,并且不用担心引用刚刚描述的信息,因为我只是想在此时更新图表。

public class FragmentOne extends Fragment implements Summary {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        return view;
    }

    @Override
    public void updateGraph() {
        BarChart theChart = (BarChart) this.getView().findViewById(R.id.chart_frag_one);
        ArrayList<BarEntry> entries = new ArrayList<>();
        List<TupleFloat> prices = new ArrayList<TupleFloat>();
        prices.add(new TupleFloat(2,4));
        prices.add(new TupleFloat(3,4));
        prices.add(new TupleFloat(1,6));
        prices.add(new TupleFloat(3,1));
        prices.add(new TupleFloat(1,1));
        prices.add(new TupleFloat(7,2));
        prices.add(new TupleFloat(3,2));

        int prices_length = prices.size(); //  need to delete

        for (int i = 1; i < prices_length+1; i++){
            entries.add(new BarEntry( (float) (i*2), new float[] {prices.get(i-1).getX(), prices.get(i-1).getY()}));
        }


        BarDataSet dataset = new BarDataSet(entries, " Summary"); // asbtract Summary
        String datas[] = {"regular", "peak"};
        dataset.setStackLabels(datas);
        dataset.setColors(new int[] {R.color.portal_dark_blue, R.color.portal_light_blue}, getActivity());


        YAxis left = theChart.getAxisLeft();
        left.setAxisMaxValue(10);//dataset.getYMax()+2);
        left.setAxisMinValue(0);
        theChart.getAxisRight().setEnabled(false);
        XAxis bottomAxis = theChart.getXAxis();
        bottomAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        bottomAxis.setValueFormatter(new AxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {

                // return values will all be the values of the dates array
                int value_i = (int) value;
                Log.d("hello", Integer.toString(value_i));

                switch(value_i){
                    case 2:
                        return "Jul 27";
                    case 4:
                        return "Jul 28";
                    case 6:
                        return "Jul 29";
                    case 8:
                        return "Jul 30";
                    case 10:
                        return "Jul 31";
                    case 12:
                        return "Aug 1";
                    case 14:
                        return "Aug 2";
                }
                return "";
            }

            @Override
            public int getDecimalDigits() {
                return 0;
            }
        });

        bottomAxis.setAxisMinValue(0);
        bottomAxis.setLabelCount(16); // size of array * 2 + 1
        bottomAxis.setAxisMaxValue(dataset.getXMax()+3); // going to be dates-array based
        bottomAxis.setDrawGridLines(false);
        theChart.setDrawValueAboveBar(false);
        theChart.setDescription("");

        BarData data = new BarData(dataset);
        theChart.setData(data);

        // legend
        Legend legend = theChart.getLegend();
        legend.setYOffset(40);
        legend.setPosition(Legend.LegendPosition.BELOW_CHART_CENTER);
        legend.setTextSize(200);
    }
}

堆栈追踪:

08-09 12:59:27.312 27094-27094/com.example.schadtj.portalapp E/AndroidRuntime: FATAL EXCEPTION: main
            Process: com.example.schadtj.portalapp, PID: 27094
            java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
                at com.example.schadtj.portalapp.FragmentOne.updateGraph(FragmentOne.java:38)
                at com.example.schadtj.portalapp.MainActivity$1.run(MainActivity.java:36)
                at android.os.Handler.handleCallback(Handler.java:739)
                at android.os.Handler.dispatchMessage(Handler.java:95)
                at android.os.Looper.loop(Looper.java:148)
                at android.app.ActivityThread.main(ActivityThread.java:5417)
                at java.lang.reflect.Method.invoke(Native Method)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Fragment_one xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fvone"
    >


    <LinearLayout
        android:id="@+id/tobegraph"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <com.github.mikephil.charting.charts.BarChart
            android:id="@+id/chart_frag_one"
            style="@style/AppTheme"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            xmlns:android="http://schemas.android.com/apk/res/android" />

    </LinearLayout>

</LinearLayout>

MainActivity必备代码

public class MainActivity extends Activity{
FragmentManager FM = getFragmentManager();
private BottomBar mBottomBar;
FragmentOne frag1;


@Override
public void onCreate(Bundle savedInstanceState) {
    // Map of Runnables
    Map<String, Runnable> rest_runnables = new HashMap<String, Runnable>();
    frag1 = new FragmentOne();
    Runnable summary = new Runnable() {
        @Override
        public void run() {
            frag1.updateGraph();
        }
    };
    rest_runnables.put("Summary", summary);
    new RestUpdateAll(this, ((MyApplication) this.getApplication()).returnUser(), rest_runnables).execute();

2 个答案:

答案 0 :(得分:0)

这显然意味着在片段视图被夸大之前已经调用了updateGraph

一个简单的解决方案是在updateGraph中添加一个简单的检查,如:

if (getView() != null){
  /* your code */
}

相反,您可以在MainActivity中添加一个检查。例如:

Fragment frg = (Fragment)getFragmentManager().findFragmentById(R.id.your_fragment);

if (frg != null){
  /* call updateGraph */
}

答案 1 :(得分:0)

请勿在此活动中致电updateGraph(请参阅您的run方法)。 Fragment在那时没有View,因此getView将返回null,如错误中所示。

FragmentOne f = new FragmentOne();
f.updateGraph(); // This is bad... Will throw error

// fragment transaction ...

相反,您可以在加载片段时更新片段的图形。你的&#34; runnable&#34;如果您希望定期刷新此视图,则应以某种方式附加到Fragment。

public class FragmentOne extends Fragment implements Summary {

    private BarChart theChart;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        theChart = (BarChart) view.findViewById(R.id.chart_frag_one);
        // Any other findViewById...

        return view;
    }

    @Override
    public void updateGraph() {

        ArrayList<BarEntry> entries = new ArrayList<>();
        List<TupleFloat> prices = new ArrayList<TupleFloat>();
        prices.add(new TupleFloat(2,4));
        ...