【问题标题】:convert JSON to contentvalues将 JSON 转换为内容值
【发布时间】:2013-04-04 18:54:11
【问题描述】:

是否有一种简单的方法可以从 web 服务获取 JSON 并将其放入我的 SQLite DB 中的 C# mono for android (xamarin)? 有一些乏味的方法可以做到,但我想要一些快速而优雅的方法。

【问题讨论】:

  • 你知道 JSON 会是什么样子,还是你需要处理任意 JSON? SQL 数据库要求您在存储内容之前了解要存储的列。

标签: android sqlite reflection xamarin.android


【解决方案1】:

这个问题很老了,但这里是@gghuffer 在 Java 中的等效代码:

public static ContentValues objectToContentValues(Object o) throws IllegalAccessException {
    ContentValues cv = new ContentValues();

    for (Field field : o.getClass().getFields()) {
        Object value = field.get(o);
        //check if compatible with contentvalues
        if (value instanceof Double || value instanceof Integer || value instanceof R.string || value instanceof Boolean
                || value instanceof Long || value instanceof Float || value instanceof Short) {
            cv.put(field.getName(), value.toString());
            Log.d("CVLOOP", field.getName() + ":" + value.toString());
        } else if (value instanceof Date) {
            cv.put(field.getName(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date)value));
        }
    }

    return cv;
}

为此,您需要使用Gson 的库并为您的所有json 定义java 类(即1 个对象 - 1 个json),然后,对于每个类,您需要实现以下部分代码:

 public static YourClass fromJSON(String dpJSON) {
        Gson gson = new Gson();
        return gson.fromJson(dpJSON, YourClass.class);
 }

最后,你有你的json字符串jsonStr,所以:

ContentValues cv = Util.objectToContentValues(YourClass.fromJSON(jsonStr));

希望对你有帮助

【讨论】:

    【解决方案2】:

    我在使用@SerializedName 注释时创建了以下类来处理这个问题,它还添加了对忽略某些字段的支持。希望它可以帮助某人。

    import android.content.ContentValues;
    import com.google.gson.annotations.SerializedName;
    
    import java.lang.reflect.Field;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    
    public class ContentValuesWriter {
    
        public static ContentValues objectToContentValues(Object o, Field... ignoredFields) {
            try {
                ContentValues values = new ContentValues();
    
                //Will ignore any of the fields you pass in here
                List<Field> fieldsToIgnore = Arrays.asList(ignoredFields);
    
                for(Field field : o.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
    
                    if(fieldsToIgnore.contains(field))
                        continue;
    
                    Object value = field.get(object);
                    if(value != null) {
                        //This part just makes sure the content values can handle the field
                        if(value instanceof Double || value instanceof Integer || value instanceof String || value instanceof Boolean
                                || value instanceof Long || value instanceof Float || value instanceof Short) {
                            values.put(field.getAnnotation(SerializedName.class).value(), value.toString());
                        }
                        else if (value instanceof Date)
                            values.put(field.getName(), Constants.DATE_FORMAT_FULL.format((Date) value));
                        else
                            throw new IllegalArgumentException("value could not be handled by field: " + value.toString());
                    }
                    else
                        Print.log("value is null, so we don't include it");
                }
    
                return values;
            } catch(Exception e) {
                Print.exception(e);
                throw new NullPointerException("content values failed to build");
            }
        }
    
    }
    

    你需要替换一些我的应用程序自定义的东西,只是日期格式和打印功能。

    【讨论】:

      【解决方案3】:

      我创建了一个静态类,它将使用反射将任何对象转换为内容值。我确信在 Java 中有一种等效的方法可以做到这一点。 将您的 JSON 对象放入某种类中,这会将所有属性转换为内容值。

      public static class Util
      {
          //suck all of the data out of a class and put it into a ContentValues object for use in SQLite Database stuff
          public static ContentValues ReflectToContentValues(object o)
          {
              ContentValues cv = new ContentValues();
      
              foreach (var props in o.GetType().GetProperties())
              {
                  object val = props.GetValue(o, null);
                  //check if compatible with contentvalues (sbyte and byte[] are also compatible, but will you ever use them in an SQLite database?
                  if (props.CanRead && props.CanWrite && (val is double || val is int || val is string || val is bool || val is long || val is float || val is short))
                  {
                      cv.Put(props.Name, val.ToString());
                      Log.Info("CVLOOP", props.Name + ":" + val.ToString());
                  }
                  else if (val is DateTime)
                      cv.Put(props.Name, ((DateTime)val).ToString("yyyy-MM-dd HH:mm:ss"));
              }
      
              return cv;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-06-27
        • 2022-01-25
        • 2019-11-20
        • 2021-12-28
        • 1970-01-01
        • 2012-12-19
        • 2020-04-14
        • 2020-10-22
        • 1970-01-01
        相关资源
        最近更新 更多