Android开发时图片Bitmap序列化问题(How to fix a java.io.NotSerializableException: android.graphics.Bitmap)

本文介绍了解决Android中Bitmap对象序列化导致的NotSerializableException错误的方法。通过重写Bitmap的序列化过程,并将Bitmap转换为字节数组进行存储,实现了对象的有效保存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文转自Stack Overflow:

http://stackoverflow.com/questions/8955034/how-to-fix-a-java-io-notserializableexception-android-graphics-bitmap

一般报错为: java.io.NotSerializableException: android.graphics.Bitmap

解决方案为在序列化对象中,为Bitmap手工写一个序列化方法。



具体参见:

How to fix a java.io.NotSerializableException: android.graphics.Bitmap

Hello im trying to save a image location on sreen to internal storage but I get a NotSerializableException.I went searching and found that the problem is that Bitmap is not designed to be serialized at this link Problem serializing Drawable I never really understood how he fix the problem throw the example. if someone could explain how he fix his NotSerializableException and help me get with mine it would be greatly appreciated


Here is my 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);
 }

 }

Here is my onTouch method in my Panel class

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

Here is my write element method in my main class

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

Update

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


}
share | improve this question
 
 
Your problem is not only Bitmap, but also Canvas and Matrix. Neither of those classes is Serializable. What are you actually trying to do? –  Peter Knego Jan 21 '12 at 17:36
 
@PeterKnego im trying to have it were the user can touch the screen and place a image of somesort on the screen but also be able to drag all the images that he places so when he fill the screen he can drag it and get more space.That why I have the matrix.After he done place what he want I like it for him to save what he done so I need the canvas forsaving to internal storage.Does that answer your qustion? in short im trying to make a level editor for a game –  Brandon Yantz Jan 21 '12 at 17:53

2 Answers 2

I just ran into the same problem. As Peter pointed out, several Classes that you use are not Serializable.

The default mechanism of Java will try to serialize your class that you marked as Serializable and try to persist all fields not marked as transient. If one of these fields however is not Serializable (such as android.graphics.Bitmap), then the call to ObjectOutputStream.writeObject will fail.

To work around this, you will need to override how Java serializes your Element class. For my CachedBitmap class, I used the following code.

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

}

For Canvasand Matrix you will need to find suitable (serializable) representations to store them in. For example, you could use the Matrix.getValues() and Matrix.setValues(...) method to translate it into a serializable format.

Hope this helps you. You might also to want to consult the following reference material by Oracle concerning Serialization: Basics and Advanced


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值