2016-11-16 9 views
0

私はJacksonを使用してCharacterオブジェクトをシリアル化しようとしています。 mapper.writeValueメソッドの呼び出しは、それはそう成功するが、私はmapper.readValueを使用して値を読み取るしようとすると、次のエラーメッセージが出ます:Jackson 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; 
    } 
} 

Iが持続し、データを読み取るために使用しているコード:

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のBitmapはテキスト形式(例えば、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); 
関連する問題