Mobiltelefonapplikationer med J2ME: Lektion 9

Idag: Lagring av data i ett postlager ("record store")

Klicka på startknappen i den lilla mediespelaren ovan för att lyssna på lektionen. (Man kan behöva vänta en stund på att ljudfilen laddas ner.) Om mediespelaren inte syns, eller om det inte fungerar av något annat skäl, kan man klicka här för att ladda ner mp3-filen (ca 18 minuter, ca 8 megabyte). Beroende på hur webbläsaren är konfigurerad kan det kräva ett separat mp3-spelarprogram av något slag.

Bild 1: Postlager

Ett postlager (på engelska: "record store") är en sorts databas som låter en MIDlet-svit lagra data persistent.

Ett postlager som råkar heta "kalle"

Kommentar: Det är inte säkert att id-numren aldrig kommer att återanvändas. Till sist lär ju räknaren slå runt.

"Bild" 2: Hur man skapar ett postlager

Ur programmet EnklaPoster från filen EnklaPoster.java:

import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
try {
    RecordStore postlagret =
        RecordStore.openRecordStore("mitt-postlager", true);
    postlagret.closeRecordStore();
}
catch (RecordStoreException e) {
    // Det gick inte att skapa postlagret
}

"Bild" 3: Hur man kommer åt ett existerande postlager

try {
    RecordStore postlagret =
        RecordStore.openRecordStore("mitt-postlager", false);

    // Här kan man jobba med postlagret

    postlagret.closeRecordStore();
}
catch (RecordStoreException e) {
    // Det gick inte att komma åt postlagret
}

"Bild" 4: Hur man lägger in en post i postlagret

private int senaste_postens_id;
try {
    RecordStore postlagret =
        RecordStore.openRecordStore("mitt-postlager", false);

    String strängen = "Det här är postens innehåll.";
    byte[] data = strängen.getBytes();
    senaste_postens_id =
        postlagret.addRecord(data, 0, data.length);

    postlagret.closeRecordStore();
}
catch (RecordStoreException e) {
    // Det gick inte att lägga in posten
}

"Bild" 5: Hur man hämtar en post från postlagret

import javax.microedition.rms.InvalidRecordIDException;
try {
    RecordStore postlagret =
        RecordStore.openRecordStore("mitt-postlager", false);

    byte[] data = postlagret.getRecord(senaste_postens_id);
    String strängen = new String(data);
    print("Post " + senaste_postens_id + ": '" + strängen + "'");

    postlagret.closeRecordStore();
}
catch (InvalidRecordIDException e) {
    // Det finns ingen post med det numret
}
catch (RecordStoreException e) {
    // Något annat fel
}

"Bild" 6: Metoden print

Metoden print lägger bara till text i en TextBox, så man kan se vad som händer. (Alla detaljerna finns i programmet EnklaPoster, på filen EnklaPoster.java.)

textrutan = new TextBox("Poster", "Hej, hej!", 2000, 0);
private void print(String s) {
    textrutan.setString(textrutan.getString() + s + "\n");
}

Bild 7: Metoden print skriver ut i en TextBox

Utskrifter med print

"Bild" 8: Hur man tar bort en post ur postlagret

try {
    RecordStore postlagret =
        RecordStore.openRecordStore("mitt-postlager", false);
    postlagret.deleteRecord(senaste_postens_id);
    postlagret.closeRecordStore();
}
catch (InvalidRecordIDException e) {
    // Det fanns ingen post med det numret
}
catch (RecordStoreException e) {
    // Något annat fel
}

"Bild" 9: Hur man går igenom alla posterna (det dumma sättet)

Ur programmet ListaPosterna från filen ListaPosterna.java:

    1	print("Posterna i postlagret:\n");
    2	
    3	try {
    4	    RecordStore postlagret =
    5	        RecordStore.openRecordStore("mitt-postlager", false);
    6	
    7	    for (int id = 0; id < 100; ++id) {
    8	        try {
    9	            byte[] data = postlagret.getRecord(id);
   10	            String strängen = new String(data);
   11	            print("Post " + id + ": '" + strängen + "'");
   12	        }
   13	        catch (InvalidRecordIDException e) {
   14	            // Posten med det numret finns inte
   15	        }
   16	    }
   17	
   18	    postlagret.closeRecordStore();
   19	    print("Klart!");
   20	}
   21	catch (RecordStoreException e) {
   22	    print("Det gick inte att visa posterna.");
   23	}
   24	print("Lista: Klart.");

Bild 10: Provkörning av det dumma sättet

En postlista på det dumma sättet

"Bild" 11: Hur man går igenom alla posterna (ett bättre sätt)

        import javax.microedition.rms.RecordEnumeration;
    1	print("Posterna i postlagret:\n");
    2	
    3	try {
    4	    RecordStore postlagret =
    5	        RecordStore.openRecordStore("mitt-postlager", false);
    6	    RecordEnumeration re =
    7	        postlagret.enumerateRecords(null, null, false);
    8	
    9	    while (re.hasNextElement()) {
   10	        byte[] data = re.nextRecord();
   11	        String strängen = new String(data);
   12	        print("Post: '" + strängen + "'");
   13	    }
   14	
   15	    re.destroy();
   16	    postlagret.closeRecordStore();
   17	    print("Klart!");
   18	}
   19	catch (RecordStoreException e) {
   20	    print("Det gick inte att visa posterna.");
   21	}
   22	print("Lista: Klart.");

Bild 12: Provkörning av det bättre sättet

En postlista på det bättre sättet

Läsanvisningar

Den här lektionen motsvaras av kapitel 8, Persistent Storage I: MIDP Record Store, i kursboken.

Den här lektionen ger grunderna för vad ett postlager är och hur man använder det, men man behöver läsa i boken också, till exempel för att förstå hur man arbetar med RecordEnumeration.

Här är några frågor som kan användas som instuderingsfrågor:

  1. Det här med postlager, är det något som hör till CLDC eller MIDP?
  2. Har det någon betydelse om postlagren finns i CLDC eller MIDP?
  3. Normalt är det bara MIDletar i samma MIDlet-svit som kommer åt ett postlager, men hur gör man för att låta flera olika applikationer (alltså flera olika MIDlet-sviter) kommer åt postlagret?
  4. openRecordStore kan bland annat kasta undantaget RecordStoreNotFoundException. Vad kan ha gått snett om ett sådant undantag kastas?
  5. openRecordStore kan bland annat kasta undantaget RecordStoreFullException. Vad kan ha gått snett om ett sådant undantag kastas?
  6. Varför vill man ibland bry sig om att anropa closeRecordStore?
  7. Hur kan man lista alla postlager som är åtkomliga?
  8. Nu skrev jag ett program som listar alla postlager. Jag vet att en del program som jag har installerade på min mobiltelefon använder sig av postlager, men ändå visas det inga postlager när jag provkör. Vad kan det bero på?
  9. Hur kan ett program kontrollera om platsen i postlagret håller på att ta slut?
  10. Hur kan ett program ta reda på när innehåller i ett postlager senast ändrades?
  11. Hur använder man metoden addRecord? (Tala både om vad den gör, och hur man skriver i programmet.)
  12. Hur använder man metoden getRecord?
  13. Metoden getRecord returnerar ju data i en byte-array. Kan det innebära prestandaproblem, och vad kan man göra åt det?
  14. Hur använder man metoden deleteRecord?
  15. Hur använder man metoden setRecord?
  16. Vad använder man ett RecordFilter till?
  17. Om vi antar att vi lagrar strängar i ett postlager, som i exemplen ovan (se också programmet EnklaPoster.java), hur ser då ett RecordFilter ut som filtrerar fram alla poster som innehåller strängar som börjar på bokstaven A?
  18. Vad använder man en RecordComparator till?
  19. Om vi antar att vi lagrar strängar i ett postlager, som i exemplen ovan (se också programmet EnklaPoster.java), hur ser då en RecordComparator ut som sorterar posterna i vanlig bokstavsordning?
  20. Vad använder man en RecordEnumeration till?
  21. Vad har man för nytta av metoden hasNextElement?
  22. Vad är skillnaden mellan de två metoderna nextRecord och getRecord?
  23. Vad är skillnaden mellan de två metoderna nextRecord och nextRecordId?
Om du vill skriva svar på instuderingsfrågorna, räcker det för de flesta frågorna med en eller några få meningar.

Programmeringsövningar

  1. Provkör MIDleten EnklaPoster (finns på filen EnklaPoster.java).
  2. Lägg till ett nytt kommando kallat Ändra i EnklaPoster. Kommandot ska ändra innehållet i den senast inlagda posten, den vars id-nummer finns i variabeln senaste_postens_id. Den ska lägga till ett utropstecken sist i strängen. (Kör man kommandot flera gånger, ska det förstås bli flera utropstecken.)
  3. Lägg till ett kommando kallat Töm i EnklaPoster, som tömmer postlagret genom att radera alla posterna.
  4. Lägg till ett annat kommando kallat Bygg om i EnklaPoster, som raderar själva postlagret och skapar ett nytt.
  5. Både när man kört Töm och när man kört Bygg om har man ett tomt postlager som heter mitt-postlager. Men finns det någon skillnad?
  6. Provkör MIDleten ListaPosterna (finns på filen ListaPosterna.java). Tänk på att den måste vara med i samma MIDlet-svit som EnklaPoster, om den ska kunna komma åt samma postlager.
  7. MIDleten ListaPosterna har ett kommando som heter Visa alla posterna. Lägg till ett nytt kommando som heter Visa !-poster, och som bara visar de poster som ändrats med ditt Ändra-kommando i MIDleten EnklaPoster, och som alltså har (minst) ett utropstecken sist i strängen. Använd ett RecordFilter.
  8. Ladda ner koden till RecordMIDlet från bokens webbplats, och provkör. Studera programkoden. Hår ska man lagra inte bara en utan två strängar i varje post. Hur har de löst det?

Föregående lektion | Lektionslista | Nästa lektion


Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se), 9 januari 2006