Fest Codierte Strings in strings.xml "umziehen" (Buzzword-Bingo)

  • Hallo erstmal, ich bin neu hier und hoffe, den richtigen Bereich gefunden zu haben.


    Zu meinem Problem: Zum experimentieren mit Datenbanken habe ich mir das Buzzword-Bingo aus einem c't Sonderheft über Android runtergeladen. Dort werden nun einzelne Wörter direkt im Code in die Datenbank eingegeben, ich möchte diese Wörter aber (zum späteren lokalisieren und um was zu lernen) in ein Array in der strings.xml packen. Wenn ich das mache, bekomme ich leider einen OutOfMemory Fehler, da das Array angeblich zu groß sei (gerademal 9 Einträge). Wie kann ich diesen Fehler jetzt beheben, oder bin ich einfach nur zu dumm dafür? ^^


    Die Datenbank-Activity (siehe 2. Aufruf) fast unbearbeitet :


    package de.menzerath.sibb;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;


    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;



    public class BBingoDB extends SQLiteOpenHelper {


    public final static String MAIN_TABLE="wordlists";


    private final static String ID="_id";
    public final static String TITLE="title";
    private final static String WORDS="words";


    public static class WordList {
    public long id;
    public String title;
    public String words;
    }


    private static final String MAIN_DATABASE_CREATE =
    "create table "+MAIN_TABLE
    +" (_id integer primary key autoincrement, "
    + TITLE+" text not null,"
    + WORDS+" text not null);";

    // Liste von Standard-Wörtern ==> Diese Wörter sollen in die strings.xml
    private static final List
    DEFAULT_WORDS=new ArrayList(
    Arrays.asList(
    "Android","Architektur",
    "Big Picture","Benchmark",
    "Context","Core",
    "Gadget",
    "Hut aufhaben",
    "Internet","iPhone",
    "Kundenorientiert",
    "Mobile irgendwas",
    "Netzwerk",
    "People","pro-aktiv",
    "Qualität",
    "Ressourcen","Revolution","Runde drehen",
    "Sozial","Synergie",
    "Technologie",
    "Überall",
    "Values","Virtuell","Vision",
    "Weltneuheit","Web 2.0","Win-Win",
    "Zielführend"));


    public BBingoDB(Context ctx) {
    super(ctx,MAIN_TABLE, null, 1); // DB Version festlegen, hier 1
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
    db.execSQL(MAIN_DATABASE_CREATE);
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


    }
    @Override
    public synchronized void close() {
    super.close();
    }


    public WordList getWordList(long id){
    Cursor c=null;
    try {
    c=getReadableDatabase().query(MAIN_TABLE, new String[]{ID,TITLE,WORDS},
    ID+"=?", new String[]{String.valueOf(id)}, null,null,null);
    if(!c.moveToFirst())
    return null;
    WordList wordlist=new WordList();
    wordlist.id=id;
    wordlist.title=c.getString(c.getColumnIndexOrThrow(TITLE));
    wordlist.words=c.getString(c.getColumnIndexOrThrow(WORDS));
    return wordlist;
    }
    finally {
    if (c != null)
    c.close();
    }
    }

    public long setWordList(WordList wordlist) {
    ContentValues values=new ContentValues();
    if(wordlist.id!=0)
    values.put(ID, wordlist.id);
    values.put(TITLE, wordlist.title);
    values.put(WORDS, wordlist.words);
    if(wordlist.id==0) {
    wordlist.id=getWritableDatabase().insert(MAIN_TABLE,null,values);
    }
    else {
    getWritableDatabase().update(MAIN_TABLE, values,
    ID+"=?", new String[]{String.valueOf(wordlist.id)});
    }
    return wordlist.id;
    }
    /**
    * Lege Standard-(Beispiel)Wortliste an
    * @return id der gespeicherten Wortliste
    */
    public long createDefaultWordList()
    {
    return setWordList(getDefaultWordList());
    }

    private WordList getDefaultWordList() {
    WordList wordlist = new WordList();
    wordlist.title = "IT";
    wordlist.words = listToString(DEFAULT_WORDS);
    return wordlist;
    }
    /**
    * Liefere ID der ersten gespeicherten Wortliste zur�ck,
    * als Fallback, falls die aktuelle Wortliste nicht mehr existiert
    * @return ID der Wortliste oder 0 falls Tabelle leer
    */
    public long getFirstWordListID() {
    Cursor c = null;
    try {
    c = getReadableDatabase().query(MAIN_TABLE, new String[] { ID },
    null, null, null, null, null, null);
    if (c.moveToFirst())
    return c.getLong(c.getColumnIndexOrThrow(ID));
    else
    return 0;
    } finally {
    if (c != null && !c.isClosed()) {
    c.close();
    }
    }
    }
    /**
    * Zugriff auf alle Wortlisten, sortiert nach Titel
    * @return Cursor �ber die Daten, Aufrufer muss Cursor selbst schlie�en
    */
    public Cursor getWordListsCursor() {
    return getReadableDatabase().query(MAIN_TABLE, new String[]{ID,TITLE},
    null, null, null,null,
    TITLE+" COLLATE LOCALIZED"); // sortiere nach Titel, Sortierreihenfolge der aktuellen Sprache
    }

    public void removeWordList(long id) {
    getWritableDatabase().delete(MAIN_TABLE, "_id=" + id, null);
    }

    // Hilfsfunktionen zur Konvertierung von Java-Listen in \n-getrennte Strings und umgekehrt
    public static String listToString(List list)
    {
    Iterator iter = list.iterator();
    StringBuffer words=new StringBuffer(iter.next());
    while(iter.hasNext())
    words.append("\n").append(iter.next());
    return words.toString();
    }
    public static List stringToList(String string)
    {
    return Arrays.asList(string.split("\n"));
    }
    }



    Wenn ich diesen wichtigen Teil jetzt jedoch durch dies ersetze:


    private static final List DEFAULT_WORDS=new ArrayList(R.array.Words1);


    Bekomme ich den bekannten OutOfMemory-Fehler.


    Die strings.xml Datei (der wichtige Ausschnitt):



    <string-array
    name="Words1">
    <item>Mathematik</item>
    <item>Hausaufgabe</item>
    <item>Füller</item>
    <item>Nachsitzen</item>
    <item>Raus!</item>
    <item>Pizza</item>
    <item>Pause</item>
    <item>Richtig</item>
    <item>Falsch</item>
    </string-array>
    Wie man jetzt sieht, habe ich bereits Wörter geändert, da meine Version zu einem "School Is Boring! Bingo" werden soll.


    Schon jetzt einmal vielen Dank an alle, die mir weiterhelfen können!


    PS: Wer mir außerdem sagen kann, wie ich weitere Listen direkt mit der App ausliefern kann, hilft mir auch sehr viel weiter!

  • hi MaMen,


    so greifst du auf das Array zu:

    Code
    String[] bingoWörter = getResources().getStringArray(R.array.Words1);


    Zitat

    Wer mir außerdem sagen kann, wie ich weitere Listen direkt mit der App ausliefern kann, hilft mir auch sehr viel weiter! ]


    meinst du damit andere "BingoWörterlisten"?
    Weil wenn ja mach doch einfach mehre Arrays in der XML.


    Mfg Titus

  • Leider funktioniert das nicht, aber trotzdem schonmal danke für deine Hilfe! :D Hier habe ich mal die genauen Stellen aus dem Code kopiert:


    Aus der Datenbank-Activity (Default_Words werden definiert):


    private static final List DEFAULT_WORDS=new ArrayList(
    Arrays.asList(
    "Android","Architektur",
    "Big Picture","Benchmark",
    "Context","Core",
    "Gadget",
    "Hut aufhaben",
    "Internet","iPhone",
    "Kundenorientiert",
    "Mobile irgendwas",
    "Netzwerk",
    "People","pro-aktiv",
    "Qualität",
    "Ressourcen","Revolution","Runde drehen",
    "Sozial","Synergie",
    "Technologie",
    "Überall",
    "Values","Virtuell","Vision",
    "Weltneuheit","Web 2.0","Win-Win",
    "Zielführend"));


    Weiter drunter (Diese Liste wird als Wortliste eingerichtet):


    public long createDefaultWordList()
    {
    return setWordList(getDefaultWordList());
    }

    private WordList getDefaultWordList() {
    WordList wordlist = new WordList();
    wordlist.title = "Testwörter";
    wordlist.words = listToString(DEFAULT_WORDS);
    return wordlist;
    }


    Ich bekomme es leider irgendwie nicht hin, die Wörterliste auf das Array (R.array.Words1) zu verweisen... ;(
    Auf die Idee einfach mehrere Arrays in die strings.xml einzubauen, hätte ich eigentlich auch selber kommen können! ;)

  • Hi MaMen,


    ah ok und was geht jetzt genau nicht?
    Wie sieht den dein Aufruf aus, um die Daten aus R.array.Word1 zu lesen?
    Wo machst du diesen Aufruf?

    Code
    getResources().getStringArray(R.array.Words1);


    Weil die Funktion getResources() gehört zu Klasse Context und muss auch über diese, wenn du "ausserhalb" der Activity bist, auch aufgerufen werden.
    Also ungefähr so:

    Code
    Context ctx;
    ctx.getResources().getStringArray(R.array.Words1);


    mfg titus


    p.s nimm bitte beim nächsten mal, wenn du Code postest die Code-Tags ließt sich einfach besser

  • Hallo und danke für die schnelle Antwort!


    Der Aufruf (also die Festlegung der Wortliste zu den Wörtern) geschieht hier:


    Code
    public long createDefaultWordList()
    	{
    		return setWordList(getDefaultWordList());
    	}
    	
    	private WordList getDefaultWordList() {
    		WordList wordlist = new WordList();
    		wordlist.title = "Testwörter";
    		wordlist.words = listToString(DEFAULT_WORDS);
    		return wordlist;


    Ich bin leider noch ein Anfänger, hab deinen Vorschlag aber mal ausprobiert, aber daraufhin soll der Typ von String nach String[] geändert werden. Wenn ich das mache, geht diese Funktion ohne Probleme, aber dafür wollen alle Anderen Funktionen, in der dieser String benutzt wird (zum Aufruf und Ändern der Wörter) den Typ wieder zurückändern. Könnte ich dieses Problem nicht umgehen, indem ich zwei Variablen anlege (einmal für die Definition der Wortliste und einmal zum Aufruf der Wörter)?
    Ich kann das gesamte Projekt aber auch gerne als zip hochladen, wenn es das für dich einfacher macht.


    grüße, MaMen.

  • Hi MaMen,


    Zitat


    ...daraufhin soll der Typ von String nach String[] geändert werden


    Welche Funktion?


    Ganz ehrlich so langsam versteh ich nicht mehr wo das Problem ist weil ich dachte du möchtest ein "String Array" aus der XMl auslesen.
    Aber in dem Code den du gepostet hast seh ich davon irgendwie nix.


    in deinem ersten Post meintest du das DEFAULT_WORDS ein hartcodiertes Liste ist.

    Zitat


    private static final List DEFAULT_WORDS=new ArrayList( Arrays.asList(
    "Android","Architektur",
    "Big Picture","Benchmark",
    ......


    So weit ok wenn ich dich jetzt richtig verstehen möchtest du diese hartcodierung austauschen mit dem String Array, damit die Werte nicht mehr im Code sondern in der XML stehen.
    Aber in dem von dir geposteten Code wird nur die Variable DEFAUL_WORDS verwendet ich sehe aber nirgendwo eine Zuweisung mit den Daten aus dem String Array.



    mfg Titus

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!