You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android应用开发遇JSON异常:org.json.JSONException: No value for data

嘿,我帮你搞定这个问题!你遇到的org.json.JSONException: No value for data主要是因为JSON格式错误,再加上代码里的一些小问题,咱们一步步来解决:

首先修复JSON格式错误(这是异常的核心原因)

你的JSON文件有两处语法问题,导致解析器无法识别"data"键:

  1. 所有键名必须用双引号包裹,比如"data"而不是data
  2. 第二个对象里的"pronunciation:"b"引号配对错误,应该是"pronunciation":"b"

修正后的JSON:

{
  "data": [
    { "character": "a", "pronunciation": "a" },
    { "character": "b", "pronunciation": "b" }
  ]
}
然后优化MainActivity代码,实现切换字符功能

原来的代码有几个问题:比如固定长度数组容易越界、onCreate里提前访问未初始化的数组、没有切换字符的逻辑。这里给你调整后的代码,注释里有详细说明:

package com.example.pirama3.pirama3;
import android.content.res.Resources;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MainActivity extends AppCompatActivity {
    // 用动态List存储字符,比固定数组更灵活,避免越界
    private List<String> characterList = new ArrayList<>();
    // 记录当前显示的字符索引,实现切换功能
    private int currentIndex = 0;
    private TextView characterTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 提前初始化TextView,避免重复查找
        characterTextView = findViewById(R.id.abc);
    }

    // 按钮点击事件:第一次点击加载数据,之后点击切换字符
    public void loadGrades(View view) {
        if (characterList.isEmpty()) {
            // 数据未加载,先加载JSON
            loadAndParseJson();
        } else {
            // 数据已加载,切换到下一个字符
            showNextCharacter();
        }
    }

    // 加载raw目录下的JSON文件并解析
    private void loadAndParseJson() {
        Resources res = getResources();
        InputStream is = res.openRawResource(R.raw.test02);
        Scanner scanner = new Scanner(is);
        StringBuilder jsonBuilder = new StringBuilder();
        while (scanner.hasNextLine()) {
            jsonBuilder.append(scanner.nextLine());
        }

        try {
            JSONObject rootObj = new JSONObject(jsonBuilder.toString());
            // 用optJSONArray替代getJSONArray,避免找不到键时抛出异常
            JSONArray dataArray = rootObj.optJSONArray("data");
            if (dataArray != null) {
                for (int i = 0; i < dataArray.length(); i++) {
                    JSONObject charObj = dataArray.getJSONObject(i);
                    // 用optString获取字符,找不到时返回空字符串
                    String character = charObj.optString("character", "");
                    if (!character.isEmpty()) {
                        characterList.add(character);
                        Log.d("Loaded Character", character);
                    }
                }
                // 加载完成后显示第一个字符
                characterTextView.setText(characterList.get(currentIndex));
            } else {
                Log.e("JSON Error", "找不到data数组");
                characterTextView.setText("数据加载失败");
            }
        } catch (JSONException e) {
            e.printStackTrace();
            characterTextView.setText("JSON解析出错");
        }
    }

    // 切换到下一个字符,循环显示
    private void showNextCharacter() {
        if (characterList.isEmpty()) return;
        // 用取模实现循环,到最后一个字符后回到第一个
        currentIndex = (currentIndex + 1) % characterList.size();
        characterTextView.setText(characterList.get(currentIndex));
    }
}
代码调整说明
  • JSON解析优化:用optJSONArrayoptString替代get方法,减少不必要的异常,同时添加错误提示;
  • 切换逻辑实现:新增currentIndex计数器,点击按钮时递增并取模,实现循环切换字符;
  • 避免空指针:提前初始化TextView,数据加载完成后再显示内容,避免访问未初始化的数组;
  • 动态数据存储:用ArrayList代替固定长度数组,适配JSON中不同数量的字符数据。

这样调整后,不仅能解决你遇到的JSON异常,还能完美实现点击按钮切换字符的功能啦!

内容的提问来源于stack exchange,提问作者Jackson Smith

火山引擎 最新活动