ImagineThat ImagineThat - 4 months ago 11
Android Question

java.lang.RuntimeException: writeValueXml: unable to write value

I am trying to successfully store and retrieve an arraylist of URIs. I'm not entirely sure where to put the 'storing' part, but it made sense to put it in onPause. My app crashes when I try to leave the activity though. I got a similar error when I tried to put it in onStop originally. Please help know what I'm doing wrong here.

FATAL EXCEPTION: main


Process: my.package.myapplication, PID: 9357
java.lang.RuntimeException: Unable to pause activity {my.package.myapplication/my.package.myapplication.Person1Screen}: java.lang.RuntimeException: writeValueXml: unable to write value content://com.android.providers.media.documents/document/image%3A49684
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3395)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3354)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3329)
at android.app.ActivityThread.access$1100(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5477)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.RuntimeException: writeValueXml: unable to write value content://com.android.providers.media.documents/document/image%3A49684
at com.android.internal.util.XmlUtils.writeValueXml(XmlUtils.java:710)
at com.android.internal.util.XmlUtils.writeValueXml(XmlUtils.java:620)
at com.android.internal.util.XmlUtils.writeSetXml(XmlUtils.java:356)
at com.android.internal.util.XmlUtils.writeValueXml(XmlUtils.java:693)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:300)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:269)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:235)
at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:192)
at android.app.SharedPreferencesImpl.writeToFile(SharedPreferencesImpl.java:600)
at android.app.SharedPreferencesImpl.access$800(SharedPreferencesImpl.java:52)
at android.app.SharedPreferencesImpl$2.run(SharedPreferencesImpl.java:515)
at android.app.SharedPreferencesImpl.enqueueDiskWrite(SharedPreferencesImpl.java:536)
at android.app.SharedPreferencesImpl.access$100(SharedPreferencesImpl.java:52)
at android.app.SharedPreferencesImpl$EditorImpl.commit(SharedPreferencesImpl.java:458)
at my.package.myapplication.Person1Screen.onPause(Person1Screen.java:257)
at android.app.Activity.performPause(Activity.java:6557)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1312)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3381)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3354) 
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3329) 
at android.app.ActivityThread.access$1100(ActivityThread.java:157) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5477) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 


My onPause method is below. Person1Screen.java:257 is the editor.commit line at the end.

@Override
protected void onPause(){
super.onPause();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREF_FILE, 0);
SharedPreferences.Editor editor = settings.edit();
Set<String> tempSet = new HashSet(happyList);
editor.putStringSet(HAPPY_LIST, tempSet);
editor.commit();
}


My retrieval in my onCreate (in case it helps):

// Restore preferences
SharedPreferences settings = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
Set<String> tempSet = settings.getStringSet(HAPPY_LIST, null);
if(tempSet != null)
for (String str : tempSet)
happyList.add(Uri.parse(str));


"happyList" is of type
ArrayList<Uri>
.

Answer

It looks like you're performing an unchecked generic assignment from HashSet to Set<String>, where the set actually contains Uri objects. When you attempt to write this set to preferences, the code attempts to read a String but actually gets a Uri object, causing the crash. To fix this, you should convert your Uri objects back into Strings.

So replace this line:

Set<String> tempSet = new HashSet(happyList);

with:

Set<String> tempSet = new HashSet<String>();
for (Uri uri : happyList) {
    tempSet.add(uri.toString());
}