你好我试图将sreen上的图像位置保存到内部存储但是我得到一个NotSerializableException。我去搜索并发现问题是Bitmap不是为了在这个链接上序列化Problem serializing Drawable我从来没有真的明白他如何解决问题抛出这个例子。如果有人可以解释他如何修复他的NotSerializableException并帮助我与我相处,那将非常感激
这是我的Elememt Class
public class Element extends main implements Serializable{
private int mX;
private int mY;
int location2 ;
Matrix elementlocation;
private Bitmap mBitmap;
Canvas canvas2;
public Element(Resources res, int x, int y) {
location2 =item3;
mBitmap = BitmapFactory.decodeResource(res, location2);
mX = x - mBitmap.getWidth() / 2;
mY = y - mBitmap.getHeight() / 2;
}
public Element(){
}
public void doDraw2(Canvas canvas) {
elementlocation=new Matrix();
elementlocation.postTranslate(mX,mY);
canvas2=canvas;
canvas2.drawBitmap(mBitmap, elementlocation,null);
}
public void setelementlocation(float num1,float num2){
elementlocation=new Matrix();
elementlocation.postTranslate(num1,num2);
}
public Canvas getCanvas2(){
return(canvas2);
}
public String toString() {
String sentence;
sentence= mBitmap+" "+mX+" "+mY;
return (sentence);
}
}
这是我的Panel类
中的onTouch方法public boolean onTouchEvent(MotionEvent event) {
mainactivity=new main();
Log.v("test", "you have touched the sreen: ");
mElements.add(new Element(getResources(),(int) event.getX(),(int) event.get()));
mainactivity.writeElement(new Element(getResources(),(int) event.getX(),(int) event.getY()),this.getContext());
Log.v("Gesture", "is 1 ");
return super.onTouchEvent(event);
}
这是我的主要课程中的写元素方法
public void writeElement(Element obj, Context context){
Log.v("main", "made it to method writeElement" );
File f = new File(context.getFilesDir(),FILENAME);
try {
fos = new FileOutputStream(f);
ObjectOutputStream objectwrite = new ObjectOutputStream(fos);
objectwrite.writeObject(obj);
fos.close();
Log.v("main", "file was made File ");
}catch (FileNotFoundException e){
e.printStackTrace();
Log.v("main", "file was not made File not found ");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v("main", "file was not made File IOException ");
}
}
更新
public Element(Resources res, int x, int y) {
location2 =item3;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
mBitmap = BitmapFactory.decodeResource(res, location2);
mX = x - mBitmap.getWidth() / 2;
mY = y - mBitmap.getHeight() / 2;
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
}
答案 0 :(得分:9)
我遇到了同样的问题。 正如彼得所指出的,你使用的几个类不是Serializable。
Java的默认机制将尝试序列化您标记为Serializable的类,并尝试保留未标记为transient
的所有字段。
但是,如果其中一个字段不 Serializable(例如android.graphics.Bitmap),那么对ObjectOutputStream.writeObject的调用将失败。
要解决此问题,您需要覆盖Java序列化Element类的方式。 对于我的CachedBitmap类,我使用了以下代码。
package XXX;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import org.apache.commons.io.output.ByteArrayOutputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class CachedBitmap implements Serializable{
private static final long serialVersionUID = -6298516694275121291L;
Date inserted;
transient Bitmap bitmap;
String url;
public CachedBitmap(){};
public CachedBitmap(Bitmap b, Date insertionDate, String sourceUrl){
bitmap = b;
inserted = insertionDate;
url = sourceUrl;
}
private void writeObject(ObjectOutputStream oos) throws IOException{
// This will serialize all fields that you did not mark with 'transient'
// (Java's default behaviour)
oos.defaultWriteObject();
// Now, manually serialize all transient fields that you want to be serialized
if(bitmap!=null){
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
boolean success = bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
if(success){
oos.writeObject(byteStream.toByteArray());
}
}
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
// Now, all again, deserializing - in the SAME ORDER!
// All non-transient fields
ois.defaultReadObject();
// All other fields that you serialized
byte[] image = (byte[]) ois.readObject();
if(image != null && image.length > 0){
bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
}
}
}
对于Canvas
和Matrix
,您需要找到合适的(可序列化的)表示来存储它们。例如,您可以使用Matrix.getValues()
和Matrix.setValues(...)
方法将其翻译成可序列化的格式。
答案 1 :(得分:2)
您的问题不仅是Bitmap
,还有Canvas
和Matrix
。这些课程都不是Serializable
。
您不需要序列化整个Element
对象,只需序列化相关数据,例如Matrix
的参数,当然还有Bitmap
。
用于序列化位图:
bmp.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
和Matrix
// get matrix values
float[] matrixValues = new float[9];
matrix.getValues(matrixValues);
// float[] to byte[]
ByteBuffer byteBuf = ByteBuffer.allocate(4 * array.length);
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
floatBuf.put(array);
byte [] byte_array = byteBuf.array();
// write data
outputStream.write(byte_array);