奇怪的JSON(逻辑)错误?

时间:2012-03-30 14:01:30

标签: android json android-asynctask

Hello Android程序员,

我正致力于在我的应用程序中解析网站。

这是网站:https://raw.github.com/currencybot/open-exchange-rates/master/latest.json

此代码段的问题在于它没有按顺序获得费率

    private class DownloadWebPageTask extends AsyncTask<String, Void, ArrayList<Double>>
{
    protected ArrayList<Double> doInBackground(String... urls)
    {
        ArrayList<Double> response = new ArrayList<Double>();
        for (String url : urls)
        {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try
            {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();
                InputStreamReader isr = new InputStreamReader(content);
                StringBuilder sb = new StringBuilder();
                char[] buffer = new char[1024];
                while (isr.read(buffer) != -1)
                {
                    sb.append(buffer);
                }
                JSONObject jobj = new JSONObject(sb.toString());
                JSONObject ratesObj = jobj.getJSONObject("rates");
                Iterator<String> keys = ratesObj.keys();
                while (keys.hasNext())
                {
                    response.add(Double.parseDouble(ratesObj.getString(keys.next())));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }
    @Override
    protected void onPostExecute(ArrayList<Double> result)
    { 
        currency_values = result;
    }

为了测试这个类,我使用了以下代码行:

   test.setText(currency_values.get(0).toString()); //test is a TextView

答案应该是3.6733(如果你看一下网站),因为它是ArrayList中的第一个速率。但是,它返回82.894997,后来在JPY下找到。

为什么会这样?有人有解决方法吗?

2 个答案:

答案 0 :(得分:0)

那是因为JSONObject可能使用简单的Map(不是排序的)来存储字段/值组合。实际上,解决方案是更新您的JSON。问题是你需要一组费率。像这样:

 "rates": [
    { "AED": 3.6733 },
    {"AFN": 48.32},
    {"ALL": 104.959999},
    ...
 ]

实际上,我说谎,费率应该是这样的:

{ "key": "AED",
  "value": 3.6733 
}

编辑: 要对结果进行排序,首先将它们存储到具有String字段和Double字段的对象中,然后您可以按名称对它们进行排序并按顺序显示它们。

答案 1 :(得分:0)

如果您查看Android文档,它会说:

  

返回此对象中String名称的迭代器。归来了   iterator支持remove,这将删除相应的映射   从这个对象。如果在迭代器之后修改此对象   返回,迭代器的行为是未定义的。 键的顺序   未定义。

因此,您必须使用其他方法。也许试试JSONObject.names()?或者,只需将所有键值对添加到数组中,然后对其进行排序,然后使用该顺序,因为它看起来只是一个简单的字母排序。