You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android JSON解析错误:null无法转为JSONObject及折线图绘制求助

解决JSON解析错误与折线图绘制问题

我帮你排查了代码里的问题,这个JSON解析错误主要是几个细节处理不当导致的,咱们一步步修复:

关键错误点分析

  • data变量初始值脏数据:data默认是null,拼接时会在JSON开头多出null字符串,直接破坏格式
  • JSON类型判断错误:返回的是JSON数组(以[开头),你却用JSONObject解析,类型不匹配
  • 集合未初始化:arrayListData只声明没创建实例,后续添加数据会触发空指针异常
  • 流读取逻辑缺陷:当前循环会把最后一次readLine()返回的null也拼进data,进一步破坏JSON格式

修复后的完整代码

package com.example.arpok.iomatic;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

public class Graph_Fragment extends androidx.fragment.app.Fragment {
    LineGraphSeries<DataPoint> series;
    ArrayList<HashMap<String, String>> arrayListData;
    public static String data = ""; // 初始化空字符串,避免null拼接
    TextView graphOneTV, graphTwoTV, graphThreeTV;
    GraphView graph;

    public Graph_Fragment() { }

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

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        graphOneTV = view.findViewById(R.id.TVGraph1);
        graphTwoTV = view.findViewById(R.id.TVGraph2);
        graphThreeTV = view.findViewById(R.id.TVGraph3);
        graph = view.findViewById(R.id.graph1);
        
        arrayListData = new ArrayList<>(); // 初始化集合,避免空指针
        graphDataClass gdc = new graphDataClass();
        gdc.execute();
    }

    public class graphDataClass extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... strings) {
            try {
                URL url = new URL("http://192.168.1.34/getGraphData.php?");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = connection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                
                String line;
                // 修正流读取逻辑:先读line,非null再拼接
                while ((line = bufferedReader.readLine()) != null) {
                    data += line;
                }

                // 解析JSON数组(返回数据是[]包裹的数组格式)
                JSONArray jsonArray = new JSONArray(data);
                for(int i=0; i<jsonArray.length(); i++) { // 循环数组长度,而非字符串长度
                    JSONObject jo = jsonArray.getJSONObject(i);
                    String twitter = jo.getString("twitter");
                    String googleplus = jo.getString("googleplus");
                    System.out.print("x: "+twitter+" y: "+googleplus);
                    
                    HashMap<String, String> tempHashMapData = new HashMap<>();
                    tempHashMapData.put("twitter", twitter);
                    tempHashMapData.put("googleplus", googleplus);
                    arrayListData.add(tempHashMapData);
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s ) {
            super.onPostExecute(s);
            graphOneTV.setText(data);
            // 在主线程绘制折线图(AsyncTask的onPostExecute运行在主线程)
            drawLineGraph();
        }
    }

    // 折线图绘制方法
    private void drawLineGraph() {
        if(arrayListData.isEmpty()) return;
        
        // 准备Twitter数据的折线点
        DataPoint[] twitterPoints = new DataPoint[arrayListData.size()];
        // 准备GooglePlus数据的折线点(如果需要双折线)
        DataPoint[] googlePlusPoints = new DataPoint[arrayListData.size()];
        
        for(int i=0; i<arrayListData.size(); i++) {
            double twitterValue = Double.parseDouble(arrayListData.get(i).get("twitter"));
            double googlePlusValue = Double.parseDouble(arrayListData.get(i).get("googleplus"));
            // 用索引作为X轴,数值作为Y轴,可根据需求调整X轴逻辑
            twitterPoints[i] = new DataPoint(i, twitterValue);
            googlePlusPoints[i] = new DataPoint(i, googlePlusValue);
        }

        // 添加Twitter折线
        LineGraphSeries<DataPoint> twitterSeries = new LineGraphSeries<>(twitterPoints);
        graph.addSeries(twitterSeries);
        // 配置Twitter折线样式
        twitterSeries.setColor(getResources().getColor(R.color.blue));
        twitterSeries.setDrawDataPoints(true);
        twitterSeries.setDataPointsRadius(8);
        twitterSeries.setThickness(3);

        // 可选:添加GooglePlus折线
        LineGraphSeries<DataPoint> googleSeries = new LineGraphSeries<>(googlePlusPoints);
        graph.addSeries(googleSeries);
        googleSeries.setColor(getResources().getColor(R.color.red));
        googleSeries.setDrawDataPoints(true);
        googleSeries.setDataPointsRadius(8);
        googleSeries.setThickness(3);
    }
}

修复细节说明

  1. data初始化:把public static String data;改成public static String data = "";,避免null字符串污染JSON内容
  2. 流读取逻辑修正:改成while ((line = bufferedReader.readLine()) != null),确保只读取有效内容,不会把null拼进JSON
  3. JSON解析调整:用JSONArray jsonArray = new JSONArray(data);解析数组,循环数组长度而非字符串长度,逐个取出内部的JSONObject
  4. 集合初始化:在onViewCreated里添加arrayListData = new ArrayList<>();,避免空指针异常
  5. 折线图绘制:新增drawLineGraph()方法,在onPostExecute中调用(保证在主线程操作UI),把字符串数据转为数值类型,生成折线点并配置样式

额外注意事项

  • 确保项目中已正确引入GraphView依赖(如果使用gradle,需在build.gradle中添加对应依赖)
  • 网络权限配置:在AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />;Android 9及以上需在application标签添加android:usesCleartextTraffic="true"允许明文HTTP请求

内容的提问来源于stack exchange,提问作者AKSHAY POKLE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:57:21