2016-11-16 62 views
0

我试图使用杰克逊序列化我的Character对象。该mapper.writeValue方法调用成功似乎,但是当我尝试使用mapper.readValue的阅读价值,我得到了以下错误消息:杰克逊找不到适合于android.graphics.Bitmap的构造函数

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of android.graphics.Bitmap: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?) 
at [Source: [email protected]; line: 1, column: 199] (through reference chain: java.lang.Object[][0]->com.myproj.character.Character["compositeClothes"]->com.myproj.character.clothing.CompositeClothing["clothes"]->java.util.ArrayList[0]->com.myproj.character.clothing.concrete.Hat["bitmap"]) 

这些都是我的课:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") 
@JsonSubTypes({ 
     @JsonSubTypes.Type(value = Hat.class, name = "hat"), 
     @JsonSubTypes.Type(value = Necklace.class, name = "necklace"), 
     @JsonSubTypes.Type(value = Shirt.class, name = "shirt") 
}) 
public interface Clothing { 
    int getCoolness(); 

    int getrId(); 

    Bitmap getBitmap(); 
} 

我的帽子类:

public class Hat implements Clothing { 
    private int rId; 
    private int coolness; 
    private Bitmap bitmap; 

    @JsonCreator 
    public Hat(@JsonProperty("coolness") int coolness, @JsonProperty("bitmap") Bitmap bitmap) { 
     rId = R.id.hat_image; 
     this.coolness = coolness; 
     this.bitmap = bitmap; 
    } 

    public int getrId() { 
     return rId; 
    } 

    @Override 
    public int getCoolness() { 
     return coolness; 
    } 

    public Bitmap getBitmap() { 
     return bitmap; 
    } 
} 

我复合服装类:

public class CompositeClothing implements Clothing, Iterable<Clothing> { 
    @JsonProperty("coolness") 
    private int coolness = 0; 
    private List<Clothing> clothes = new ArrayList<>(); 

    public void add(Clothing clothing) { 
     clothes.add(clothing); 
    } 

    public void remove(Clothing clothing) { 
     clothes.remove(clothing); 
    } 

    public Clothing getChild(int index) { 
     if (index >= 0 && index < clothes.size()) { 
      return clothes.get(index); 
     } else { 
      return null; 
     } 
    } 

    @Override 
    public Iterator<Clothing> iterator() { 
     return clothes.iterator(); 
    } 

    @Override 
    public int getCoolness() { 
     return coolness; 
    } 

    @Override 
    public int getrId() { 
     return 0; 
    } 

    @Override 
    public Bitmap getBitmap() { 
     return null; 
    } 
} 

而且我的性格类:

public class Character implements Observable { 
    private static final transient Character instance = new Character(); 

    @JsonProperty("compositeClothes") 
    private CompositeClothing clothes = new CompositeClothing(); 
    @JsonProperty("compositeHeadFeatures") 
    private CompositeHeadFeature headFeatures = new CompositeHeadFeature(); 

    private transient List<Observer> observers = new ArrayList<>(); 

    @JsonProperty("skin") 
    private Skin skin; 

    public void attach(Observer observer) { 
     observers.add(observer); 
    } 

    public void notifyAllObservers() { 
     for (Observer observer : observers) { 
      observer.update(); 
     } 
    } 

    public void setSkin(Skin skin) { 
     this.skin = skin; 
     notifyAllObservers(); 
    } 

    public Skin.Color getSkinColor() { 
     return skin.getColor(); 
    } 

    public Bitmap getSkinBitmap() { 
     return skin.getBitmap(); 
    } 

    public boolean hasSkin() { 
     return skin != null; 
    } 

    public void addClothing(Clothing clothing) { 
     Clothing oldClothing = (Clothing) getSameTypeObjectAlreadyWorn(clothing); 

     if (oldClothing != null) { 
      clothes.remove(oldClothing); 
     } 

     clothes.add(clothing); 
     notifyAllObservers(); 
    } 

    public CompositeClothing getClothes() { 
     return clothes; 
    } 

    private Object getSameTypeObjectAlreadyWorn(Object newClothing) { 
     Class<?> newClass = newClothing.getClass(); 

     for (Object clothing : clothes) { 
      if (clothing.getClass().equals(newClass)) { 
       return clothing; 
      } 
     } 

     return null; 
    } 

    public void removeClothing(Clothing clothing) { 
     clothes.remove(clothing); 
    } 

    public void addHeadFeature(HeadFeature headFeature) { 
     HeadFeature oldHeadFeature = (HeadFeature) getSameTypeObjectAlreadyWorn(headFeature); 

     if (oldHeadFeature != null) { 
      headFeatures.remove(oldHeadFeature); 
     } 

     headFeatures.add(headFeature); 
     notifyAllObservers(); 
    } 

    public void removeHeadFeature(HeadFeature headFeature) { 
     headFeatures.remove(headFeature); 
    } 

    public CompositeHeadFeature getHeadFeatures() { 
     return headFeatures; 
    } 

    public static Character getInstance() { 
     return instance; 
    } 
} 

,我使用坚持,然后读取数据的代码:

File charactersFile = new File(getFilesDir() + File.separator + "characters.ser"); 
ObjectMapper mapper = new ObjectMapper() 
     .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE) 
     .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 

try (FileWriter fileOut = new FileWriter(charactersFile, false)) { 
    List<Character> characters = Arrays.asList(character); 
    mapper.writeValue(fileOut, characters); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

Character[] characters = null; 
try (FileReader fileIn = new FileReader(charactersFile)) { 
    characters = mapper.readValue(fileIn, Character[].class); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

谢谢!

+1

把一个' JSON中的位图需要将其转换为一些文本格式(例如base64)。我会推荐做其他事情,而不是试图把位图放入JSON中。这些位图来自哪里? – CommonsWare

+0

来自我随应用附带的资产。也许我可以将我的位图转换为一个字节[],或者只是使用路径?事情是新的,“布料”将在稍后由用户添加到应用中,并且这些将被存储在内部存储装置中,这将使得我想要定位它更难一些。 – masm64

回答

0

如果您的位图来自资产或资源,将位图保存到JSON没有意义。这将浪费CPU时间和磁盘空间。相反,请将值存储在JSON中,以便您可以识别要显示的资产或资源。但是,请记住,资源ID(例如,R.drawable.foo)可能因应用程序版本而异,因此这不是图像的良好持久标识符。

+0

我想我需要将getAssetManager()+“clothing/...”路径或getInternalStorage()+“clothing/...”路径存储/添加到相应的对象。 – masm64

0

我在我的应用程序中有类似的需求,我需要将可绘制数据存储在JSON中。我通过只存储它的字符串名来解决它。举例来说,如果我有资源R.drawable.testBmp然后我把它保存在JSON,如:

{ 
    ... 
    "mydrawable" : "testBmp" 
} 

在运行的时候,我会读它,并转化为像下面的代码绘制:

JSONObject jsonObj; 
... 
String bmpName = jsonObj.getString("mydrawable");   
int resId = context.getResources().getIdentifier(bmpName, 
            "drawable", 
            context.getPackageName()); 
Drawable bmp = ContextCompat.getDrawable(context,resId); 
相关问题