Java Android-如何解析JSON数组中的特定值并显示Toast

Java Android-如何解析JSON数组中的特定值并显示Toast,java,android,json,Java,Android,Json,一般来说,我对Android和Java都是新手,我正在学习如何进行JSON调用。为此,我遵循以下指南: 这就是让我感到困惑的地方。该教程的作者希望读者调用以下API: 返回以下格式的JSON对象: { "weatherObservation": { "clouds":"scattered clouds", "weatherCondition":"n/a",

一般来说,我对Android和Java都是新手,我正在学习如何进行JSON调用。为此,我遵循以下指南:

这就是让我感到困惑的地方。该教程的作者希望读者调用以下API:

返回以下格式的JSON对象:

            {
                "weatherObservation": {
                     "clouds":"scattered clouds",
                     "weatherCondition":"n/a",
                     "observation":"KCFV 090852Z AUTO 06005KT 
                      10SM SCT090 SCT110 24/20 A3000 RMK AO2 
                      SLP148 T02390200 53002",
                     "windDirection":60,
                     "ICAO":"KCFV",
                     "seaLevelPressure":1014.8,
                     "elevation":225,
                     "countryCode":"US",
                     "lng":-95.56666666666666,
                     "temperature":"23.9",
                     "dewPoint":"20",
                     "windSpeed":"05",
                     "humidity":78,
                     "stationName":"Coffeyville, Coffeyville 
                                 Municipal Airport",
                     "datetime":"2012-07-09 08:52:00",
                     "lat":37.083333333333336
                }
            }
非常简单,只是API不再有效/有限制。为了完成项目,我选择调用以下API:

以这种格式返回JSON

{
    "coord": {
        "lon": 139,
        "lat": 35
    },
    "sys": {
        "country": "JP",
        "sunrise": 1369769524,
        "sunset": 1369821049
    },
    "weather": [
        {
            "id": 804,
            "main": "clouds",
            "description": "overcast clouds",
            "icon": "04n"
        }
    ],
    "main": {
        "temp": 289.5,
        "humidity": 89,
        "pressure": 1013,
        "temp_min": 287.04,
        "temp_max": 292.04
    },
    "wind": {
        "speed": 7.31,
        "deg": 187.002
    },
    "rain": {
        "3h": 0
    },
    "clouds": {
        "all": 92
    },
    "dt": 1369824698,
    "id": 1851632,
    "name": "Shuzenji",
    "cod": 200
}
我可以很好地进行调用,但是如何在天气数组中显示main和description字符串呢?更具体地说,如何在祝酒辞中显示此信息

以下是我所拥有的:

protected void onPostExecute(String result){

        try {


            JSONArray weatherArray = new JSONArray(result);
            JSONArray wArray = new JSONArray("weather");

            String mainWeather = wArray.getString(1);
            String mainDescription = wArray.getString(2);

            Toast.makeText(getBaseContext(), mainWeather + " - "
                        + mainDescription,Toast.LENGTH_SHORT).show();

        } catch (Exception e) {
            Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
        }
因为我遵循mobiforge教程,所以除了这段特殊的代码之外,我没有偏离任何地方

谢谢你的帮助

编辑: 这里有几种可行的解决方案,请参见@swats和@user3515851。我选择@remees-m-syde是因为它简单。主要是因为他的解决方案不需要我通过for循环

用这个

                JSONObject weatherArray = new JSONObject(result);
                JSONArray wArray = new JSONArray("weather");

                String mainWeather = ((JSONObject)wArray.getJSONObject(0)).getString("main");
                String mainDescription = ((JSONObject)wArray.getJSONObject(0)).getString("description");

                Toast.makeText(getBaseContext(), mainWeather + " - "
                            + mainDescription,Toast.LENGTH_SHORT).show();

我假设您现在通过解析这个JSON来获取天气数组,以从中检索值

JSONObject  object=null;
try {
            JSONObject  object=array.getJSONObject(0);
            String main=object.getString("main");  
            String description=object.getString("description");

        } catch (JSONException e) {
            e.printStackTrace();
        }

现在使用toast中的字符串

您无法获取数据,因为weather JSONArray中有一个json对象

JSONArray以-[

JSONObject以-{开头

因此,首先获取JSONArray,然后获取其中的JSONObject

"weather": [                          ----Array
        {                             ----Object
            "id": 804,
            "main": "clouds",
            "description": "overcast clouds",
            "icon": "04n"
        }
    ]
您必须获取这个JSONObject,然后从中获取字符串,如下面的代码所示

    JSONObject weatherArray = new JSONObject(result);
    JSONArray wArray = weatherArray.getJSONArray("weather");
    JSONObject jobj = wArray.getJSONObject(0);
    String mainWeather = jobj.getString("main");
    String mainDescription = jobj.getString("description");
    Toast.makeText(getBaseContext(), mainWeather + " - "
                                + mainDescription,Toast.LENGTH_SHORT).show();
当数组中有多个对象时,按如下方式获取它

JSONObject rootJsonObj = new JSONObject(result);
     JSONArray wArray = rootJsonObj.optJSONArray("weather");
     for (int i = 0; i < wArray.length(); i++) {
          JSONObject weatherJsonObj = wArray.getJSONObject(i);
          String mainWeather = weatherJsonObj.getString("main");
          String mainDescription = weatherJsonObj.getString("description");

          Toast.makeText(getBaseContext(), mainWeather + " - "
                      + mainDescription,Toast.LENGTH_SHORT).show();
     }

我希望这篇文章能对您有所帮助:

假设结果包含JSON,下面是如何获取main和description表单:

  JSONObject resJSON = new JSONObject(result);
  JSONArray weatherArray = resJSON.getJSONArray("weather");

  for(int i = 0; i < weatherArray.length(); i++) {
      JSONObject weatherJSON = weatherArray.getJSONObject(i);
      System.out.println(weatherJSON.getString("main"));
      System.out.println(weatherJSON.getString("description"));
  }
试试这个

    JSONObject weatherObject = new JSONObject(result);
    JSONArray wArray = weatherObject.getJSONArray("weather");
    for (int i = 0; i < wArray.length(); i++) {
      JSONObject wObject = wArray.getJSONObject(i);
      if(wObject.has("description")) {
        Log.d("TAG", wObject.getString("description"));
      }
      if(wObject.has("main")) {
        Log.d("TAG", wObject.getString("main"));
      }
    }
最近,我发现了一个有用的json解析工具,可以与Jackson、Gson、Java等任何东西一起使用。 希望这会对您有所帮助。

我使用了optJSONArray或optString,而不是getJSONArray或getString,因为如果该键没有值,opt将返回。它不会像getString那样引发任何异常

试试下面的代码

     JSONObject rootJsonObj = new JSONObject(result);
     JSONArray wArray = rootJsonObj.optJSONArray("weather");
     for (int i = 0; i < wArray.length(); i++) {
          JSONObject weatherJsonObj = wArray.optJSONObject(i);
          String mainWeather = weatherJsonObj.optString("main");
          String mainDescription = weatherJsonObj.optString("description");

          Toast.makeText(getBaseContext(), mainWeather + " - "
                      + mainDescription,Toast.LENGTH_SHORT).show();
     }
若存在解析问题,则应该从响应结果中获取对象



编辑:在使用optJSONArray或optString时,不需要try-catch块。

当存在像Quicker xml Jackson这样的神奇库时,为什么要使用JSONObject等?@Hector这里没有必要给出负面评价。答案是绝对正确的,如果android已经提供了支持,为什么要添加任何第三方库omment?哪个词或短语是否定的?android提供的解决方案在性能和简单性方面已经足够了。让我们不要满足于我们想到的第一个解决方案。为什么不花一些时间研究替代方案并使用更快的xml Jackson进行Json解析?@user3515851我在上述代码中遵循了约定。如果您使用了相同的解决方案所以它的代码。这并不意味着我复制了你的代码。斯瓦蒂·阿加瓦尔:是的,你是从我的代码中复制的。这就是我要说的。这样一个令人恼火的家伙,我使用了optString方法,你没有。所以在评论之前再仔细检查一下。@swatiagarwal不需要在这里使用try catch block。你应该看看Gson。它会改变你的生活到java中的json解析。您创建一个与json结果匹配的简单对象,并使用gson解析它。非常直接谢谢Neil。我了解了基本知识后将对此进行研究。您想知道关于gson主题的答案吗?不,谢谢,现在不想。我仍在想为什么这里的解决方案有效/无效。嗨,Pramod-为了使用您的解决方案,我必须先解析JSON?如果我总是想要一组特定的值,为什么我要/需要这样做?谢谢!因为您无法在不解析JSON的情况下获取天气数组,因为它是您获得的JSON输出的一部分,所以要获取JSON数组,您必须从您的输出中解析它如果您需要,我更希望您应该使用jackson或gson库来处理JSON。这实际上解决了我的问题。您能解释一下原因吗?我假设有必要通过数组获取值?您好-您的解决方案提供了以下错误:“D/ReadWeatherJSONFeedTask”﹕ 无法将java.lang.String类型的Value weather转换为JSONArray“您能在weather注释中详细说明您的对象吗?谢谢您的帮助!很有效!我实际上更喜欢您的解决方案,因为我不必单步执行for循环。不过,有两个问题:为什么您的解决方案不必单步执行for循环?为什么要将0放入inside wArray.getJSONObject?因为在您的响应中,您只得到一个对象,如{},所以我得到的是第0个位置的第一个对象。如果有n个对象,您必须使用循环。所以对于任何类似的JSON,如果有固定数量的对象,我也可以这样做?设置第0个位置
打开,然后只调用我正在搜索的任何对象?对于固定json,您可以这样做,但动态您必须使用循环。仅链接的答案是不好的做法,。始终引用重要链接中最相关的部分,以防无法访问目标站点或永久脱机。
     JSONObject rootJsonObj = new JSONObject(result);
     JSONArray wArray = rootJsonObj.optJSONArray("weather");
     for (int i = 0; i < wArray.length(); i++) {
          JSONObject weatherJsonObj = wArray.optJSONObject(i);
          String mainWeather = weatherJsonObj.optString("main");
          String mainDescription = weatherJsonObj.optString("description");

          Toast.makeText(getBaseContext(), mainWeather + " - "
                      + mainDescription,Toast.LENGTH_SHORT).show();
     }