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

Android解析JSON为Java对象数组报No value for name错误

问题背景

Android开发过程中需要采集接口返回的JSON数据,解析为Java对象后存入对象数组,后续用于ListView和Fragment的数据展示。代码可正常启动运行,但日志输出JSON解析报错,此前尝试直接用JSONArray解析也未成功。

原有实现代码
import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    ArrayList<Character> characterArray = new ArrayList<Character>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CharacterGetData characterGetData = new CharacterGetData();
        characterGetData.execute("https://swapi.dev/api/people/?format=json");
    }

//Character Class
class Character{
       String name;
       String height;
       String mass;

}

    class CharacterGetData extends AsyncTask<String, String, String> {
        String name;
        String height;
        String mass;


        @Override
        protected String doInBackground(String... args) {

            try {

                URL obj = new URL(args[0]);
                HttpURLConnection connection = (HttpURLConnection) obj.openConnection();
                connection.setRequestMethod("GET");


                BufferedReader in = new BufferedReader(
                        new InputStreamReader(connection.getInputStream()));
                String line;
                StringBuffer response = new StringBuffer();
                while ((line = in.readLine()) != null) {
                    response.append(line);

                }
                in.close();

                JSONObject jsonObj = new JSONObject(response.toString());
                Character character1 = new Character();
                character1.name = jsonObj.getString("name");
                character1.height = jsonObj.getString("height");
                character1.mass = jsonObj.getString("mass");
                characterArray.add(character1);


                Log.i("MainActivity", "The name is " + character1.name + "the height is " + character1.height);


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException | JSONException e) {
                e.printStackTrace();
            }
            return null;
        }
    }}
运行报错日志
W/System.err: org.json.JSONException: No value for name
W/System.err:     at org.json.JSONObject.get(JSONObject.java:400)
W/System.err:     at org.json.JSONObject.getString(JSONObject.java:561)
W/System.err:     at com.example.androidlabs.MainActivity$CharacterGetData.doInBackground(MainActivity.java:71)
W/System.err:     at com.example.androidlabs.MainActivity$CharacterGetData.doInBackground(MainActivity.java:43)
W/System.err:     at android.os.AsyncTask$3.call(AsyncTask.java:394)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err:     at java.lang.Thread.run(Thread.java:923)
接口返回结构

调用接口地址:https://swapi.dev/api/people/?format=json
返回JSON结构如下:

{"count":82,"next":"https://swapi.dev/api/people/?page=2&format=json","previous":null,"results":[{"name":"Luke Skywalker","height":"172","mass":"77","hair_color":"blond","skin_color":"fair","eye_color":"blue","birth_year":"19BBY","gender":"male","homeworld":"https://swapi.dev/api/planets/1/","films":["https://swapi.dev/api/films/1/","https://swapi.dev/api/films/2/","https://swapi.dev/api/films/3/","https://swapi.dev/api/films/6/"],"species":[],"vehicles":["https://swapi.dev/api/vehicles/14/","https://swapi.dev/api/vehicles/30/"],"starships":["https://swapi.dev/api/starships/12/","https://swapi.dev/api/starships/22/"],"created":"2014-12-09T13:50:51.644000Z","edited":"2014-12-20T21:17:56.891000Z","url":"https://swapi.dev/api/people/1/"}]}
报错原因

解析逻辑层级错误:接口返回的最外层JSON对象仅包含count、next、previous、results四个字段,name/height/mass等人物属性字段都存在于results对应的JSON数组的子元素中,直接在最外层对象调用getString("name")自然会触发「No value for name」异常。

修复方案
  • 调整JSON解析层级,先从最外层对象取出results对应的JSON数组
  • 遍历该数组,逐个取出每个人物对应的JSON子对象
  • 从子对象中解析目标字段,封装为Character实例存入列表

核心修复后的解析代码如下:

JSONObject jsonObj = new JSONObject(response.toString());
// 取出外层包裹的人物列表数组
JSONArray resultArr = jsonObj.getJSONArray("results");
// 遍历数组解析所有人物数据
for (int i = 0; i < resultArr.length(); i++) {
    JSONObject characterItem = resultArr.getJSONObject(i);
    Character character = new Character();
    character.name = characterItem.getString("name");
    character.height = characterItem.getString("height");
    character.mass = characterItem.getString("mass");
    characterArray.add(character);
    Log.i("MainActivity", "The name is " + character.name + " the height is " + character.height);
}

额外优化建议

  • 解析字段时优先使用optString()替代getString(),字段不存在时会默认返回空字符串,避免直接抛出异常崩溃,提升代码健壮性
  • 记得在AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />权限,否则高版本Android系统会拦截网络请求
  • AsyncTask已在Android 11版本被官方废弃,后续可改用Retrofit/OkHttp等网络框架配合协程、线程池实现网络请求,减少版本兼容问题

内容的提问来源于stack exchange,提问作者newbie-coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:36:26