将JSON转换为contentvalues

时间:2013-04-04 18:54:11

标签: android sqlite reflection xamarin.android

是否有一种简单的方法可以从Web服务获取JSON并将其放入C#mono for android(xamarin)的SQLite DB中? 有一些繁琐的方法,但我想要一些快速和优雅的东西。

3 个答案:

答案 0 :(得分:4)

问题是陈旧的,但这里是Java中@gghuffer的等效代码:

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));

希望这有帮助

答案 1 :(得分:1)

我在使用@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");
        }
    }

}

您需要在我的应用中替换一些自定义内容,只需更换日期格式和打印功能。

答案 2 :(得分:0)

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

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;
    }

}