简体   繁体   English

Jackson没有为android.graphics.Bitmap找到合适的构造函数

[英]Jackson no suitable constructor found for android.graphics.Bitmap

I'm trying to serialize my Character object with the use of Jackson. 我正在尝试使用Jackson来序列化我的Character对象。 The mapper.writeValue method invocation is successful it seems, but when I try to read the value with the use of mapper.readValue I get the following error message: 看起来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"])

These are my classes: 这些是我的课程:

@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();
}

My hat class: 我的帽子课:

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

My composite clothing class: 我的复合服装班:

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

And my character class: 我的角色课:

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

The code that I'm using to persist and then read the data: 我用来保留然后读取数据的代码:

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

Thanks! 谢谢!

If your bitmaps come from assets or resources, there is no point on saving the bitmaps to JSON. 如果位图来自资产或资源,则将位图保存为JSON毫无意义。 That would be a waste of CPU time and disk space. 那将浪费CPU时间和磁盘空间。 Instead, store a value in the JSON that will allow you to identify the asset or resource to display. 而是在JSON中存储一个值,该值将允许您标识要显示的资产或资源。 However, bear in mind that resource IDs (eg, R.drawable.foo ) can vary between app releases, so that is not a good durable identifier for the image. 但是,请记住,资源ID(例如R.drawable.foo )在应用程序发行版之间可能会有所不同,因此这不是图像的良好持久标识符。

I have similar requirement in my app where I need to store drawable data in JSON. 我的应用程序中有类似的要求,我需要在JSON中存储可绘制数据。 I solved it by storing only its string name. 我通过仅存储其字符串名称来解决它。 For example, if I have resource R.drawable.testBmp then I store it in JSON like : 例如,如果我有资源R.drawable.testBmp则将其存储在JSON中,如下所示:

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

Then at run time, I will read it and convert is as drawable like following code: 然后在运行时,我将阅读它并进行转换,就像下面的代码一样可绘制:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jackson ObjectMapper冲突的setter定义(Android.Graphics.Bitmap) - Jackson ObjectMapper Conflicting setter definitions (Android.Graphics.Bitmap) 在没有Android的情况下从Java使用android.graphics.Bitmap - Use android.graphics.Bitmap from Java without Android 从C ++创建android.graphics.Bitmap - Creating an android.graphics.Bitmap from C++ Java中的android.graphics.Bitmap序列化和反序列化 - Serializing and De-Serializing android.graphics.Bitmap in Java org.mapsforge.core.graphics.Bitmap和android.graphics.Bitmap之间的任何关系方法 - Any relation method between org.mapsforge.core.graphics.Bitmap and android.graphics.Bitmap Android - 找不到合适的构造函数 - Android - No suitable constructor found 方法&#39;boolean android.graphics.Bitmap.compress(android.graphics.Bitmap $ CompressFormat,int,java.io.OutputStream) - method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream) kotlin.TypeCastException:null无法强制转换为非null类型android.graphics.Bitmap - kotlin.TypeCastException: null cannot be cast to non-null type android.graphics.Bitmap 尝试在空对象引用上调用虚拟方法&#39;void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)&#39; - Attempt to invoke virtual method 'void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference 杰克逊错误:没有合适的构造函数 - Jackson error: no suitable constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM