2015-04-12 94 views
3

我想通過使用.putExtra()和sendBroadcast()從IntentService發送一些工作到BroadcastReceiver,所以我有自己的類稱爲「消息」,它擴展了HashMap <字符串,字符串>和實現Serializable。Casting可派生的哈希映射

public class Message extends HashMap<String,String> implements Serializable{ 
    public MessageID ID; 
    public int Encode(byte[] buff,int off); 
    public int Decode(byte[] buff,int off); 
    //... 
} 

而且我發送這樣的:

public static void ProcessMessage(Message msg) { 
    Intent broadcastIntent = new Intent(); 
    broadcastIntent.setAction(Receiver.BROADCAST); 
    broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
    broadcastIntent.putExtra("MESSAGE",(Serializable)msg); 
    parentService.sendBroadcast(broadcastIntent); 
    Print("Broadcasting intent to receiver ("+Receiver.BROADCAST+") from: "+parentService.toString()); 
} 

和接收這樣的:

public void onReceive(Context context, Intent intent) { 
    Sys.Print("Receiver handling: "+intent.getAction()); 
    if(intent.getAction().equals(BROADCAST)){ 
     try { 
      Message msg = (Message) intent.getSerializableExtra("MESSAGE"); 
      Sys.Print("Receiver handling " + msg.ID.toString()); 
     } catch(Exception ex){ 
      Sys.Print("Failed handling message, reason: "+ex.getStackTrace().toString()); 
     } 
    } 
} 

但在這裏,我總是得到這樣的:"Failed handling message, reason: java.lang.ClassCastException: java.util.HashMap"

任何想法可能是什麼是錯的?

棧跟蹤:

com.myapp.Receiver.onReceive(Receiver.java:24) 
android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:709) 
android.os.Handler.handleCallback(Handler.java:587) 
android.os.Handler.dispatchMessage(Handler.java:92) 
android.os.Looper.loop(Looper.java:138) 
android.app.ActivityThread.main(ActivityThread.java:3701) 
java.lang.reflect.Method.invokeNative(Native Method) 
java.lang.reflect.Method.invoke(Method.java:507) 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878) 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) 
dalvik.system.NativeStart.main(Native Method) 

所以最後,如果任何人有類似的問題,我解決了這個問題是這樣的:

public class Message implements Parcelable { 
    public HashMap<String,String> Data; 
    public Message(){ 
     Data=new HashMap<>(); 
    } 
    public int Encode(byte[] buff,int off); 
    public int Decode(byte[] buff,int off); 
    public void Add(String i,String v); 
    public String At(String i); 
    public boolean ContainsKey(String i); 
    @Override 
    public int describeContents() { 
     return 0; 
    } 
    @Override 
    public void writeToParcel(Parcel out, int flags) { 
     out.writeMap(this.Data); 
    } 
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
     public Message createFromParcel(Parcel in) { 
      return new Message(in); 
     } 
     public Message[] newArray(int size) { 
      return new Message[size]; 
     } 
    }; 
    public Message(Parcel in) { 
     Data=new HashMap<>(); 
     in.readMap(this.Data,String.class.getClassLoader()); 
    } 
} 
+1

地方整個堆棧跟蹤,請您在使用同一個JVM上。雙方? – Zielu

+0

我直接在設備上運行它。 – jakubinf

回答

1

你不會喜歡這個答案。

其他存儲在Bundle。 Android對Bundle的內容做了一些「優化」,它試圖在知道它的類型時如何序列化/反序列化條目。所以,如果你把任何一個實現Map接口爲Bundle,當你把它找回來了,你將有一個HashMap :-(

對力學的詳細說明請參見my answer to this question

解決你的問題,你需要讓你的自定義類使用(即:包含)一HashMap而不是(即:從繼承)一個HashMap

1

這是一個錯誤(但,不固定)在Android SDK中。在bug report這是一個ArrayList,但它也適用於實現MapList的類。

在bug報告,有人使用下面的持有人作爲一個修復建議:

public class SerializableHolder implements Serializable { 
    private Serializable content; 
    public Serializable get() { 
     return content; 
    } 
    public SerializableHolder(Serializable content) { 
     this.content = content; 
    } 
} 

,但我的建議是,以代替實施Parcelable,這是Android製成,比Serializable快了一大堆。

+0

現在我總是碰到,那getParcelableExtra(「MESSAGE」)總是返回null,並且''broadcastIntent.putExtra(「MESSAGE」,(Parcelable)msg);' – jakubinf

+0

「bug」與實現'Serializable無關'。該錯誤與Android優化類實現'Map'或'List'接口有關。請參閱[我對這個問題的回答。](http://stackoverflow.com/a/12305459/769265) –

+0

@DavidWasser所以你說實現'Parcelable'而不是'Serializable'不會修復它? – ddmps