Reputation: 4370
FATAL EXCEPTION: AsyncTask #2
Process: my.app, PID: 15441
java.lang.ClassCastException: java.util.HashSet cannot be cast to my.app.ChatNotificationHashSet
at my.app.UserHandler.getChatNotificationMessage(UserHandler.java:127)
at my.app.NotificationUtil.getChatTitle(NotificationUtil.java:100)
at my.app.NotificationUtil.showChat(NotificationUtil.java:71)
at my.app.service.GCMListenerService.onMessageReceived(GCMListenerService.java:47)
at com.google.android.gms.gcm.GcmListenerService.zzq(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzp(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzo(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zza(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
ChatNotificationHashSet
public class ChatNotificationHashSet<E> extends LinkedHashSet<String> {
@Override
public String toString() {
// ...
}
}
UserHandler (where the exception occurs)
public ChatNotificationHashSet<String> getChatNotificationMessage() {
return (ChatNotificationHashSet<String>) pref.getStringSet(CHAT_NOTIFICATION_MESSAGE, null); // <- Exception occurs here
}
public void setChatNotificationMessage(ChatNotificationHashSet<String> messages) {
SharedPreferences.Editor editor = pref.edit();
editor.putStringSet(CHAT_NOTIFICATION_MESSAGE, messages);
editor.commit();
}
How can this happen? There shouldn't be any problems when casting null
to ChatNotificationHashSet<String>
, right? I couldn't think of any other problem.
Upvotes: 2
Views: 18020
Reputation: 2075
pref.getStringSet()
returns a HashSet
and not your class, even when it can handle your class as HashSet
while saving.
Upvotes: 1
Reputation: 4223
Values are simply copied into an existing HashSet. Your collection is only a source for the copy.
Refer the comments on this answer: https://stackoverflow.com/a/13446387/1364747
Interface used for modifying values in a SharedPreferences object. All changes you make in an editor are batched, and not copied back to the original SharedPreferences until you call commit() or apply() Source: SharedPreferences.Editor
Only after commit changes are copied to the original SharedPreferences.
Upvotes: 1
Reputation: 4370
Thank you guys. I've chosen to save the list as an simple JSON String, which works fine.
Upvotes: 0
Reputation: 6846
Exception came in your program with this line
return (ChatNotificationHashSet<String>) pref.getStringSet(CHAT_NOTIFICATION_MESSAGE, null); // <- Exception occurs here
because your ChatNotificationHashSet
class is a Strict-Type Argument (simply say generics Supported). So Type-Safety
is enabled for this class.
Here getStringSet
method return the Object of Type java.util.HashSet<String>
which is not a type of ChatNotificationHashSet<String>
.
So, Converting a HashSet<String>
type Object to ChatNotificationHashSet<String>
will prone to ClassCastException
as You see in your Code
Upvotes: 0
Reputation: 18825
The Set
that is returned by getStringSet()
does not need to be the same as you pass to SharedPreferences.Editor.putStringSet()
method. It's generally up to internal implementation. I assume it serializes the data and puts it into some storage and unserializes when retrieving back.
If you need your specific structure, it's probably better to implement some wrapper which would either read all settings in the constructor or retrieve the settings on demand from underlying Set
.
Upvotes: 3