ligate / beginning-android-games

Automatically exported from code.google.com/p/beginning-android-games
0 stars 0 forks source link

[Chapter 6] Mr Nom settings not loading properly (page 235) #31

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Basically, every time you restart MrNom, (like say turn off your phone and 
reboot your phone), your settings do not load. this includes wrong 
soundEnabled, and previous high scores are not loaded.

What steps will reproduce the problem?
1. copyright 2011 edition of book 
2. using the code from pg 235
3. Ubuntu 9.10
4. Eclipse Galileo
5. 
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2)
OpenJDK Server VM (build 19.0-b09, mixed mode)
6. latest Android tools as of Sept 9th, 2011 (which should not affect this 
error)

What is the expected output? What do you see instead?
the expected output is that the settings load properly

I'm not sure why no one else has this problem, im guessing because i'm using an 
older version of Java? 

Original issue reported on code.google.com by davidtia...@gmail.com on 10 Sep 2011 at 6:44

GoogleCodeExporter commented 9 years ago
Anyhow, i found the solution to the problem after debugging. so it turns out, 
the line:

out.write(Boolean.toString(soundEnabled));

does not actually add a newline character to the end of the string. So in other 
words, we are writing all the settings in one line, as a string, which becomes 
a problem when trying to parse that back upon loading the settings file. in 
your settings file, you get something like "true10080503010"  instead of 
"true\n100\n80\n50\n30\n10", which is the proper way to write out the file, in 
order for your "readLine()" to work later on.

As a side note, i also would prefer the name of the settings file to be in a 
directory instead of just named ".mrnom". For this one file, it's fine; 
however, in order to scale the project (like say several settings files) it's 
better to put the settings under something like "/MrNom/settings" on my SD 
card. that way i know not to erase the files also.

i'm writing the fix for the code here (in your Settings.java file, replace the 
function below):
{{{

public static void save(FileIO files){
        BufferedWriter out = null;
        try{
            out = new BufferedWriter(new OutputStreamWriter(files.writeFile(".mrnom")));
            out.write(Boolean.toString(soundEnabled) + "\n");
            for(int i=0; i<5; i++) out.write(Integer.toString(highscores[i]) + "\n");
        } catch(IOException e){}
        finally {
            try{
                if(out!=null) out.close();
            } catch (IOException e) {}
        }

    }

}}}

and notice that i changed the line from 

out.write(Integer.toString(highscores[i]));

to

out.write(Integer.toString(highscores[i]) + "\n");

because you want to actually add a delimiter.
that should make the code work.

If you want to also save the settings file in "/MrNom/settings.txt" then, you 
have to  change ".mrnom" to "settings.txt" in the Settings.java file. ALSO, you 
have to change  your AndroidFileIO.java constructor to say something like 
{{{

    public AndroidFileIO(AssetManager assets, String folderName){
        this.assets = assets;
        this.externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath() + folderName;
        File dir = new File(this.externalStoragePath);
        if(!dir.mkdirs()) Log.e("AndroidFileIO", "could not create directory: " + externalStoragePath);
    }

}}}

and that way, you end up making the directory. Now, you also have to change the 
way you call this constructor in your AndroidGame.java (which is in your 
framework implementation package) by changing

fileIO = new AndroidFileIO(getAssets());

to 

fileIO = new AndroidFileIO(getAssets(), "/MrNom/");

and that should be all the fixes you need.

P.S. i must say - this is an AWESOME BOOK!!! i LOVE it!!! it explains things so 
well, and thank you so much for publishing this book. you have certainly 
inspired another kid to be a developer :)

Original comment by davidtia...@gmail.com on 10 Sep 2011 at 7:00

GoogleCodeExporter commented 9 years ago
As Mario points out in this GREAT Book :D its better to use StringBuilder to 
concatenate strings and avoid using the + operator for performance reasons:

    public static void save(FileIO files) {
        BufferedWriter out = null;
        StringBuilder builder = new StringBuilder();
        try {
            out = new BufferedWriter(new OutputStreamWriter(
                    files.writeFile(".mrnom")));
            builder.append(Boolean.toString(soundEnabled));
            builder.append("\n");
            out.write(builder.toString());
            for (int i = 0; i < 5; i++) {
                builder.delete(0,builder.length());
                builder.append(Integer.toString(highscores[i]));
                builder.append("\n");
                out.write(builder.toString());
            }
        } catch (IOException e) {
            Log.e("IOException", e.getMessage());
        } finally {
            try {
                if (out != null)
                    out.close();
            } catch (IOException e) {
                Log.e("IOException", e.getMessage());
            }
        }
    }

Original comment by eduardo...@gmail.com on 25 Sep 2011 at 8:55

GoogleCodeExporter commented 9 years ago
or better yet:

            for (int i = 0; i < 5; i++) {
                builder.append(Integer.toString(highscores[i]));
                builder.append("\n");
            }
            out.write(builder.toString());

sry :P

Original comment by eduardo...@gmail.com on 25 Sep 2011 at 9:05