javaandroidjsonstringandroid-sharedpreferences

String stored in SharedPreferences gets modified on each app close?


So, i have been beating my mind over this problem since the last 24 hours, before i begin, let me make it clear that this problem occurs only on one of my android mobile which is running on marshmallow.

Problem:

When i retrieve a string response using StringRequest, the string is exactly how its supposed to be, then i save it to SharedPreferences, and the value remains correct (i.e. same) no matter how many times i retrieve the file from SharedPreferences. But when i close the app and relaunch it, and retrieve the string from SharedPreferences, the string changes somehow, length decreases, .equals returns false when compared with newly fetched same string from server, So i am guessing that the SharedPreferences modifies the String value on its own in Android marshmallow. after a lot of debugging, i wrote both strings (from sharedpreferences as well as the server) to separate .txt files to internal storage, and opened them both with notepad++, and Voila!, the control characters are changed from 'CR LF' to 'LF', thus causing length of string to be changed, although, the length differs, when i compare both strings on many online websites, all of them says "the strings are exactly identical!" :(

Help guys! Thnx


Solution

  • After a lot of trouble, I finally found out the root cause. On some devices, the string values stored in SharedPreferences get its EOL characters modified. The line breaks in the string gets converted to something other than \n which reduces the length of the string. Each line break will reduce the length of the string by 1 digit. The solution was simple:

    Replace all the line breaks with \n after each retrieval of string from the SharedPreferences.

    String fixedString = problemString.replace(System.getProperty("line.separator"),"\\\n" );
    

    also in case your string contains manually formatted string, which contains line break characters other than \n, you should use this:

    String fixedString = problemString.replace("\r\n|\n|\r", "\\\n");
    

    UPDATE

    The above solution will cause issues if you have a string which is already formatted with unix EOL characters, making it impossible to use if you have multiple strings formatted with different EOL characters. So the best approach I found is to simply replace only the carriage returns denoted by \r

    String fixedString = brokenString.replace("\r", "");
    

    This method will remove any carriage returns in your string, so the string gets converted to (Unix LF) format from (Windows CR LF) format. The length will decrease by 1 digit on each line break. :)