Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Json解析速度比較-Android API、Gson、Fastjson

Json解析速度比較-Android API、Gson、Fastjson

編輯:關於Android編程

IOS現成的API裡的json解析速度非常快,這裡就不說了,今天對比一下Android裡面json的解析庫。

首先第一個是Android API裡面自帶的json解析,其次是谷歌提供的Gson解析庫(開源),其次是在網上看到的解析很快速的阿裡巴巴分享的Fastjson包。Android自帶的json解析大家一定都很熟悉了,這裡不介紹了,這裡詳細說說谷歌提供的另一套解析庫Gson:

gson的使用方法非常的簡單。只需要將需要解析的json字符串和對應的Bean類xing型傳遞給GSON類的from方法既可:

Gson gson = new Gson();
            List so = gson.fromJson(mJsonString, new TypeToken>() {  
            }.getType());

這裡的beanlei類中的字段的命名要和json中的字段相同,其次實現get和set方法(稍後講原因)。

標准的bean:

import java.util.List;
                                                     
public class Geo {
                                                     
    private String type;
                                                         
    private List coordinates;
                                                         
    public Geo() {}
                                                     
    public String getType() {
        return type;
    }
                                                     
    public void setType(String type) {
        this.type = type;
    }
                                                     
    public List getCoordinates() {
        return coordinates;
    }
                                                     
    public void setCoordinates(List coordinates) {
        this.coordinates = coordinates;
    }
                                                         
}

我曾經擔心復雜的json結構會不會解析出現問題,但是試驗了以後嵌套了其他的bean類,照樣迭代賦值了。

阿裡巴巴提供的fastjson庫使用方法和gson一樣,只是底層的原理不同。這裡不詳細介紹了。

 

下面看一下三個庫解析相同的json字段的對比:(使用了25條非常復雜的Json數據)

\

 

大家可以看到谷歌提供的gson有非常大的速度優勢。這裡我們走進它的代碼浏覽一下。

找到了關鍵的類:JsonObject.java

 

package com.google.gson;
                               
import com.google.gson.internal.LinkedTreeMap;
import java.util.Map.Entry;
import java.util.Set;
                               
public final class JsonObject extends JsonElement
{
  private final LinkedTreeMap members = new LinkedTreeMap();
                               
  JsonObject deepCopy()
  {
    JsonObject result = new JsonObject();
    for (Map.Entry entry : this.members.entrySet()) {
      result.add((String)entry.getKey(), ((JsonElement)entry.getValue()).deepCopy());
    }
    return result;
  }
                               
  public void add(String property, JsonElement value)
  {
    if (value == null) {
      value = JsonNull.INSTANCE;
    }
    this.members.put(property, value);
  }
                               
  public JsonElement remove(String property)
  {
    return (JsonElement)this.members.remove(property);
  }
                               
  public void addProperty(String property, String value)
  {
    add(property, createJsonElement(value));
  }
                               
  public void addProperty(String property, Number value)
  {
    add(property, createJsonElement(value));
  }
                               
  public void addProperty(String property, Boolean value)
  {
    add(property, createJsonElement(value));
  }
                               
  public void addProperty(String property, Character value)
  {
    add(property, createJsonElement(value));
  }
                               
  private JsonElement createJsonElement(Object value)
  {
    return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value);
  }
                               
  public Set> entrySet()
  {
    return this.members.entrySet();
  }
                               
  public boolean has(String memberName)
  {
    return this.members.containsKey(memberName);
  }
                               
  public JsonElement get(String memberName)
  {
    return (JsonElement)this.members.get(memberName);
  }
                               
  public JsonPrimitive getAsJsonPrimitive(String memberName)
  {
    return (JsonPrimitive)this.members.get(memberName);
  }
                               
  public JsonArray getAsJsonArray(String memberName)
  {
    return (JsonArray)this.members.get(memberName);
  }
                               
  public JsonObject getAsJsonObject(String memberName)
  {
    return (JsonObject)this.members.get(memberName);
  }
                               
  public boolean equals(Object o)
  {
    return (o == this) || (((o instanceof JsonObject)) && (((JsonObject)o).members.equals(this.members)));
  }
                               
  public int hashCode()
  {
    return this.members.hashCode();
  }
}

 

可以看到其中使用了一個LinkedTreeMap來緩存字段與值。這裡要比我們直接使用API中的方法尋找要快,其次在類ProtoTypeAdapter.java中我們找到了賦值方法:

@SuppressWarnings("unchecked")
  @Override
  public GeneratedMessage deserialize(JsonElement json, Type typeOfT,
      JsonDeserializationContext context) throws JsonParseException {
    try {
      JsonObject jsonObject = json.getAsJsonObject();
      Class protoClass =
        (Class) typeOfT; 
      try {
        // Invoke the ProtoClass.newBuilder() method
        Object protoBuilder = getCachedMethod(protoClass, "newBuilder")
          .invoke(null);
        Class builderClass = protoBuilder.getClass();
                        
        Descriptor protoDescriptor = (Descriptor) getCachedMethod(
            protoClass, "getDescriptor").invoke(null);
        // Call setters on all of the available fields
        for (FieldDescriptor fieldDescriptor : protoDescriptor.getFields()) {
          String name = fieldDescriptor.getName();
          if (jsonObject.has(name)) {
            JsonElement jsonElement = jsonObject.get(name);
            String fieldName = name + "_";
            Field field = protoClass.getDeclaredField(fieldName);
            Type fieldType = field.getGenericType();
            Object fieldValue = context.deserialize(jsonElement, fieldType);
            Method method = getCachedMethod(
              builderClass, "setField", FieldDescriptor.class, Object.class);
            method.invoke(protoBuilder, fieldDescriptor, fieldValue);
          }
        }
                                
        // Invoke the build method to return the final proto
        return (GeneratedMessage) getCachedMethod(builderClass, "build")
            .invoke(protoBuilder);
      } catch (SecurityException e) {
        throw new JsonParseException(e);
      } catch (NoSuchMethodException e) {
        throw new JsonParseException(e);
      } catch (IllegalArgumentException e) {
        throw new JsonParseException(e);
      } catch (IllegalAccessException e) {
        throw new JsonParseException(e);
      } catch (InvocationTargetException e) {
        throw new JsonParseException(e);
      }
    } catch (Exception e) {
      throw new JsonParseException("Error while parsing proto: ", e);
    }
  }

 

這裡通過反射類的set方法來給變量賦值,因此bean類中的變量要加上get和set方法。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved