杰克逊没有为 android.graphics.Bitmap 找到合适的构造函数
Posted
技术标签:
【中文标题】杰克逊没有为 android.graphics.Bitmap 找到合适的构造函数【英文标题】:Jackson no suitable constructor found for android.graphics.Bitmap 【发布时间】:2017-03-30 01:19:21 【问题描述】:我正在尝试使用 Jackson 序列化我的 Character 对象。 mapper.writeValue 方法调用似乎是成功的,但是当我尝试使用 mapper.readValue 读取值时,我收到以下错误消息:
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: java.io.FileReader@9ab6557; 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();
谢谢!
【问题讨论】:
将Bitmap
放入 JSON 需要将其转换为某种文本格式(例如 base64)。我建议做其他事情,而不是尝试将位图放在 JSON 中。这些位图来自哪里?
来自我的应用程序附带的资产。也许我可以将我的位图转换为字节 [],或者只使用路径?事情是新的“衣服”将由用户稍后添加到应用程序中,这些将存储在内部存储中,我猜这会使定位它有点困难。
【参考方案1】:
如果您的位图来自资产或资源,则将位图保存为 JSON 是没有意义的。这将浪费 CPU 时间和磁盘空间。相反,在 JSON 中存储一个值,以便您识别要显示的资产或资源。但是,请记住,资源 ID(例如,R.drawable.foo
)可能会因应用版本而异,因此这不是图像的良好持久标识符。
【讨论】:
我想我需要将 getAssetManager() + "clothing/..." 路径或 getInternalStorage() + "clothing/..." 路径存储/添加到相应的对象.【参考方案2】:我的应用程序中有类似的要求,我需要以 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);
【讨论】:
以上是关于杰克逊没有为 android.graphics.Bitmap 找到合适的构造函数的主要内容,如果未能解决你的问题,请参考以下文章