我想序列化android.net.Uri类型的对象的状态。
下面是我的带有writeObject和readObject方法的模型类
public class ReminderObject implements Serializable {
private boolean isReminderOn;
private int fromHours, toHours;
private int interval;
private ArrayList<CharSequence> daysToRepeat;
private Uri toneToPlay;
private AdvanceSettingsObject adv;
public ReminderObject(boolean isReminderOn, int fromHours, int toHours,
int interval, ArrayList<CharSequence> daysToRepeat, Uri toneToPlay,
AdvanceSettingsObject adv) {
super();
this.isReminderOn = isReminderOn;
this.fromHours = fromHours;
this.toHours = toHours;
this.interval = interval;
this.daysToRepeat = daysToRepeat;
this.toneToPlay = toneToPlay;
this.adv = adv;
}
/*
getters and setters
*/
public void writeObject(ObjectOutputStream op){
try {
op.defaultWriteObject();
op.writeChars(toneToPlay.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void readObject(ObjectInputStream in){
try{
in.defaultReadObject();
toneToPlay = Uri.parse(in.readUTF());
}catch(Exception e){
}
}
}
MainActivity的代码段:
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/ReminderData.txt") );
os.writeObject(reminder); // Getting above mentioned Exception here
Log.i("TAG","reminder serialized");
ObjectInputStream is = new ObjectInputStream(new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/ReminderData.txt"));
ReminderObject reminderRead = (ReminderObject) is.readObject();
if(reminderRead!=null)
Log.i("TAG", "Deserialized Reminder object is : "+reminderRead.toString());
else{
Log.i("TAG", "Null received");
}
} catch(ClassNotFoundException cnf){
cnf.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
面临异常:
03-31 23:47:59.246: W/System.err(12681): java.io.NotSerializableException: android.net.Uri$HierarchicalUri
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
03-31 23:47:59.246: W/System.err(12681): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
03-31 23:47:59.246: W/System.err(12681): at com.navkar.navkarreminder.SetReminderActivity.scheduleReminder(SetReminderActivity.java:595)
请求帮助。
答案 0 :(得分:7)
我认为问题是您保存问题的数据成员。
private Uri toneToPlay
是非序列化数据类型,您无法将其序列化。
答案 1 :(得分:4)
URI private Uri toneToPlay
不可序列化。因此,有另一种方法,您可以将数据类型URI更改为String,并将URI转换为字符串,将字符串转换为URI,反之亦然。
Uri to String
Uri uri;
String stringUri;
stringUri = uri.toString();
字符串到Uri
Uri uri;
String stringUri;
uri = Uri.parse(stringUri);
答案 2 :(得分:0)
请考虑使用java.net.URI
类。这具有几乎相同的功能,但它是 Serializable
。您可以轻松地从Uri转换为URI(和向后):
Uri to URI :new URI(uri.toString())
URI到Uri :Uri.parse(uri.toString())
答案 3 :(得分:0)
一种可能的解决方案是,当我们仍然希望让Uri成为成员(例如,为了方便起见)并序列化类时,就是使Uri transient
并序列化Uri String
(用@King of群众显示)。
通过这种方式,我们不会更改POJO的公共接口,也不会序列化Uri,从而创建了一种惰性方式。
带有Uri的可序列化POJO看起来像这样:
class MediaFile implements Serializable {
private static final long serialVersionUID = -420L;
@Nullable
private transient Uri mFileUri;
@NonNull
private String mFileUriString;
MediaFile(@NonNull Uri fileUri) {
this.mFileUriString = fileUri.toString();
}
@NonNull
public getFileUri() {
if (mFileUri == null) {
mFileUri = Uri.parse(mFileUriString);
}
return mFileUri;
}
}
对于Kotlin:
class MediaFile(uri: Uri) : Serializable {
private val mUriString = uri.toString();
@Transient private val mUri by lazy { Uri.parse(mUriString) }
}