如何修复java.io.NotSerializableException:android.graphics.Bitmap

Bra*_*ntz 2 android serializable

您好我试图将图像位置保存到sreen到内部存储但是我得到一个NotSerializableException.我去搜索并发现问题是Bitmap不是为了在这个链接上 序列化问题序列化Drawable我从来没有真正理解他如何修复问题抛出这个例子.如果有人可以解释他如何修复他的NotSerializableException并帮助我与我的相处,我将不胜感激


这是我的Elememt课程

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

 }
Run Code Online (Sandbox Code Playgroud)

这是我的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);
}
Run Code Online (Sandbox Code Playgroud)

这是我的主类中的write元素方法

  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 ");
}
 }
Run Code Online (Sandbox Code Playgroud)

更新

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


}
Run Code Online (Sandbox Code Playgroud)

Pat*_*ick 10

我刚遇到同样的问题.正如Peter指出的那样,您使用的几个类不是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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

对于Canvas和,Matrix您将需要找到合适的(可序列化的)表示来存储它们.例如,您可以使用Matrix.getValues()Matrix.setValues(...)方法将其转换为可序列化的格式.

希望这对你有所帮助.您可能还想查阅Oracle关于序列化的以下参考资料:基础知识高级