【问题标题】:JSON Parsing taking too much time - AndroidJSON解析花费太多时间 - Android
【发布时间】:2016-03-30 15:41:06
【问题描述】:

我有一个 JSON 文件 airports.json,其中包含 5720 个对象,我想将 Java 中的文件解析为 Objects Airport。 下面的代码是我如何解析它的,问题是,完全解析所有文件需要花费太多时间,大约 1 分 50 秒。

    ArrayList<Airport> arrayAirports = new ArrayList<>();
    String json_response = loadJSONFromAsset();
    try {
        JSONObject airports = new JSONObject(json_response.trim());

        Log.d("Length Array 0", String.valueOf(airports.names().length()));
        Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
        for(int i = 0; i<airports.names().length(); i++){
                JSONObject jsonAirport = airports.getJSONObject(airports.names().getString(i));
                Airport newAirport = new Airport();
                newAirport.name = jsonAirport.getString("name");
                newAirport.city = jsonAirport.getString("city");
                newAirport.country = jsonAirport.getString("country");
                newAirport.latitude = jsonAirport.getString("latitude");
                newAirport.longitude = jsonAirport.getString("longitude");
                newAirport.altitude = jsonAirport.getString("altitude");
                newAirport.iata = jsonAirport.getString("iata");
                newAirport.icao = jsonAirport.getString("icao");
                newAirport.timeZone = jsonAirport.getString("timezone");
                newAirport.dst = jsonAirport.getString("dst");
                arrayAirports.add(newAirport);
        }



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

    Log.d("Length Array 2", String.valueOf(arrayAirports.size()));

有没有办法更快地解析它。 顺便说一句,我的朋友正在使用 Objective C 来解析它。

Link to JSON file

【问题讨论】:

  • 尝试使用第三方库而不是手动操作github.com/google/gson
  • 我现在正在尝试使用它,但我不知道如何循环遍历 JSON 文件并每次添加一个 Airport 对象
  • JSONObject.names() 在每次迭代中...两次?
  • 这是我能想到的唯一方法

标签: java android json parsing


【解决方案1】:

改用GSON 并用它测量速度。虽然读取文件可能需要很长时间,但一分钟似乎很糟糕。

既然你提到你不知道如何使用 GSON,here's a tutorial I wrote for a student on how to use GSON。它假设您从网络调用中获取文件,因此您需要应用它以使用本地 JSON 文件。

【讨论】:

    【解决方案2】:

    不知道这对性能是否重要,但您不应该反复致电names()。在循环之前赋值给变量,然后使用它。

    JSONArray names = airports.names();
    Log.d("Length Array 0", String.valueOf(names.length()));
    Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
    for(int i = 0; i<names.length(); i++){
        JSONObject jsonAirport = airports.getJSONObject(names.getString(i));
        // code
    }
    

    更好的是,使用length()keys()

    Log.d("Length Array 0", String.valueOf(airports.length()));
    Log.d("Length Array 1", String.valueOf(arrayAirports.size()));
    for (Iterator<String> nameIter = airports.keys(); nameIter.hasNext(); ){
        String name = nameIter.next();
        JSONObject jsonAirport = airports.getJSONObject(name);
        // code
    }
    

    【讨论】:

    • 不知道它是否对性能很重要 ...public JSONArray names() { JSONArray ja = new JSONArray(); Iterator keys = this.keys(); while (keys.hasNext()) { ja.put(keys.next()); } return ja.length() == 0 ? null : ja; } keys()的JSONArray ... 迭代 keys() 并将它的项目放到这个数组中......即使只释放这个 JSONArray(和 gc)也需要一些时间
    • @Selvin 更糟糕的是,如果对象为空,它会返回null,因此这是一种非常危险的使用方法,因为它可能会导致NullPointerException
    • 感谢它为我完成了这项工作而无需更改太多代码
    • @IlhemNemri 请注意,由于 NPE 的危险,您应该使用 keys(),而不是 names(),这对性能也更好,因为它不必将名称复制到数组优先。
    【解决方案3】:

    您正在将(我猜?)大型 JSON 数据文件直接放入 JSONObject。

    在这种情况下,建议使用基于令牌的阅读器,例如 JsonReader

    直接从文档中粘贴:

    public List readJsonStream(InputStream in ) throws IOException {
        JsonReader reader = new JsonReader(new InputStreamReader( in , "UTF-8"));
        try {
            return readMessagesArray(reader);
            finally {
                reader.close();
            }
        }
    
        public List readMessagesArray(JsonReader reader) throws IOException {
            List messages = new ArrayList();
    
            reader.beginArray();
            while (reader.hasNext()) {
                messages.add(readMessage(reader));
            }
            reader.endArray();
            return messages;
        }
    
        public Message readMessage(JsonReader reader) throws IOException {
            long id = -1;
            String text = null;
            User user = null;
            List geo = null;
    
            reader.beginObject();
            while (reader.hasNext()) {
                String name = reader.nextName();
                if (name.equals("id")) {
                    id = reader.nextLong();
                } else if (name.equals("text")) {
                    text = reader.nextString();
                } else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
                    geo = readDoublesArray(reader);
                } else if (name.equals("user")) {
                    user = readUser(reader);
                } else {
                    reader.skipValue();
                }
            }
            reader.endObject();
            return new Message(id, text, user, geo);
        }
    
        public List readDoublesArray(JsonReader reader) throws IOException {
            List doubles = new ArrayList();
    
            reader.beginArray();
            while (reader.hasNext()) {
                doubles.add(reader.nextDouble());
            }
            reader.endArray();
            return doubles;
        }
    
        public User readUser(JsonReader reader) throws IOException {
            String username = null;
            int followersCount = -1;
    
            reader.beginObject();
            while (reader.hasNext()) {
                String name = reader.nextName();
                if (name.equals("name")) {
                    username = reader.nextString();
                } else if (name.equals("followers_count")) {
                    followersCount = reader.nextInt();
                } else {
                    reader.skipValue();
                }
            }
            reader.endObject();
            return new User(username, followersCount);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多