• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Shared Preference adds unwanted characters on /n

Running on live Android 7.0 on LG G6 and Galaxy Nexus API 27 on Android Emualtor

I've encountered a known problem with Shared Preferences whereby on an app restart it will read the last character of text being stored in the string provided, and if that character is "\n" then it automatically adds 4 space characters, upon being read again in my app this messes up my game's tilemap royally as you can see in the attached before and after screenshots.

These links are cases that have encountered the issue before but no apparent fix has been given
Stackoverflow case
Google Issue Tracker

This is the text of the file I'm reading (the tilemap is primarily meant for landscape mode but rotate this 90 degrees to the right):
Code:
############00
#..00#00000###
#..00#0$00$00#
#..00#$####00#
#..0000@0##00#
#..00#0#00$0##
######0##$0$0#
00#0$00$0$0$0#
00#0000#00000#
00############

And this is the text stored within Shared Preferences once I kill the app (pausing/backing out doesn't do this)
Code:
############00
#..00#00000###
#..00#0$00$00#
#..00#$####00#
#..0000@0##00#
#..00#0#00$0##
######0##$0$0#
00#0$00$0$0$0#
00#0000#00000#
00############

This is the code I use to 'Save' my current game data to Shared Preferences:

Code:
public String serialize() {
    // This is horribly inefficient. Invoke Knuth and pass through.
    StringBuilder str = new StringBuilder();
    for(int iy = 0; iy < map_height; iy++) {
        for(int ix = 0; ix < map_width; ix++) {
            int map_code = map[(iy * map_width) + ix];
            if(ix == man_x && iy == man_y) {
                map_code = map_code | PLAYER;
            }
            switch(map_code) {
                case WALL: str.append("#"); break;
                case GOAL: str.append("."); break;
                case CRATE: str.append("$"); break;
                case PLAYER: str.append("@"); break;
                case PLACED_CRATE: str.append("!"); break;
                case PLAYER_ON_GOAL: str.append("?"); break;
                case FLOOR:
                    str.append("0");
                    break;
                default:
                    str.append("#");
                    break;
            }
        }
        str.append("\n");
    }
    return str.toString();
}

I was wondering if anyone had ideas of on how I can avoid using "/n" characters with each new line?

P.S. I tried replacing str.append("\n"); with
str.append(System.getProperty("line.separator")); but the same result occurred.
 

Attachments

  • Screenshot_Before.png
    Screenshot_Before.png
    392.6 KB · Views: 164
  • Screenshot_After.png
    Screenshot_After.png
    367 KB · Views: 166
Last edited:
If the problem occurs when your text ends with a '\n' character, then why not introduce a termination character, or string. So save your maze map like this

Code:
############00
#..00#00000###
#..00#0$00$00#
#..00#$####00#
#..0000@0##00#
#..00#0#00$0##
######0##$0$0#
00#0$00$0$0$0#
00#0000#00000#
00############
END

And when your app reloads it, you take the substring of the above, from the start, to the position of the termination string.
 
Okay, I managed to get this to work by ignoring the new line character on the last map_height row:

Code:
if (iy != (map_height - 1)){
    str.append("\n");
}

Now I just need to figure out why my map is always 1 tile's width to far into the x axis on my frame...
 
Back
Top Bottom