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); } }
修复细节说明
- data初始化:把
public static String data;改成public static String data = "";,避免null字符串污染JSON内容 - 流读取逻辑修正:改成
while ((line = bufferedReader.readLine()) != null),确保只读取有效内容,不会把null拼进JSON - JSON解析调整:用
JSONArray jsonArray = new JSONArray(data);解析数组,循环数组长度而非字符串长度,逐个取出内部的JSONObject - 集合初始化:在
onViewCreated里添加arrayListData = new ArrayList<>();,避免空指针异常 - 折线图绘制:新增
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
相关产品推荐
相关产品推荐

