2012-01-21 96 views
2

你好我試圖保存一個圖像位置屏幕上的內部存儲,但我得到一個NotSerializableException.I去搜索,發現問題是,該位圖不是旨在被鏈接到這個鏈接Problem serializing Drawable我從來沒有真正明白他是如何解決這個問題的例子。如果有人能解釋他是如何解決他的NotSerializableException,並幫助我與我得到它,將不勝感激如何解決一個java.io.NotSerializableException:android.graphics.Bitmap


這裏是我的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); 
} 

} 

這裏是我的面板在我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

您的問題不僅是'位圖',還包括'畫布'和'矩陣'。這兩個類都不是'Serializable'。你究竟在做什麼? –

+0

@PeterKnego即時通訊用戶可以觸摸屏幕並在屏幕上放置某種圖像,但也可以拖動他放置的所有圖像,這樣當他填滿屏幕時,他可以拖動屏幕並獲得更多空間。爲什麼我有這個矩陣。當他完成了他想要的東西之後,我喜歡他爲了挽救他所做的事情,所以我需要將畫布放在內部存儲空間中。是否回答你的問題?簡而言之即時試圖做一個遊戲的關卡編輯器 –

回答

2

您的問題不僅是Bitmap,也CanvasMatrix。這兩個類別都不是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); 
+0

對不起,我有點困惑是,在元素類或主要類別iv嘗試你的位圖建議在這裏什麼iv嘗試,但我不知道如果即時通訊做對了生病發布我試用 –

8

我只是碰到了同樣的問題。正如Peter指出的那樣,您使用的幾個類不是可序列化的。

Java的默認機制會嘗試序列化您標記爲可序列化的類,並嘗試保留未標記爲transient的所有字段。 但是,如果其中一個字段是而不是可序列化(如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); 
     } 
    } 

} 

對於CanvasMatrix你需要找到合適的(序列化)表示將它們存儲在。例如,你可以使用Matrix.getValues()Matrix.setValues(...)方法把它翻譯成一個序列化格式。

希望這可以幫助你。您可能還想查閱Oracle關於序列化的以下參考資料:BasicsAdvanced

+0

謝謝,這幫了我很多! – neteinstein