Persistence Versi 0.1 Pembangunan Aplikasi Mobile
Persistence
Versi 0.1
Pembangunan Aplikasi Mobile
Tujuan
Memahami Record Management System
Memahami konsep dari RecordStore
Membuat Record Store
Menambah, mengupdate, dan menghapus Records
Enumerate records menggunakan RecordEnumerator
Membuat Record Comparator
Membuat Record Filter untuk mencari sebuah Record Store
Persistence
Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Persistence
MIDP menyediakan sebuah API yang dapat menyimpan data dari aplikasi didalam local device
Data akan disimpan pada non-volatile memory didalam device
Hal ini berarti data tidak akan hilang, walaupun program di-restart maupun device di-turned off
Record Management System adalah sebuah database system yang berorientasi record bagi MIDP device
Sebuah record didalam database ini secara sederhana hanyalah sebuah array bytes dengan sebuah index
Persistence
Sebuah record store dapat terdiri dari nol record atau lebih
Digunakanlah DataInputStream, DataOutputStream, ByteArrayInputStream dan ByteArrayOutputStream untuk mendapatkan dan menyimpan berbagai tipe data dari Records ke record stores
Banyaknya data yang bisa disimpan dalam record store sangat bervariasi dari satu device ke device yang lain
MIDP specifications membutuhkan minimal 8 kB yang telah dipesan sebagai persistence storage
Persistence
javax.microedition.rms package menyediakan method-method untuk mengetahui ukuran dari record dan juga record store
Untuk mengetahui berapa byte yang tersisa dalam non-vollatile memori setelah menyimpan sebuah record store dapat ditentukan dengan getSizeAvailable() dari class RecordStore
MIDP specifications tidak memiliki batasan dari ukuran record
Ukuran dari tiap record dibatasi dengan sendirinya oleh setiap device, dimana batasan ukurannya bervariasi
Persistence
Sebuah MIDlet yang menggunakan RMS akan menspesifikasikan berapa bytes yang dibutuhkan.
Ukuran ini ditentukan dalam JAR manifest dan application descriptor(JAD) menggunakan attribute MIDlet-Data-Size
Device atau application management system (AMS) dalam device bisa menolak meng-install sebuah MIDlet suite jika ukuran byte dari RMS tidak sesuai dengan kapabilitas device
Jika attribute ini hilang, maka device akan mengansumsikan bahwa sebuah MIDlet suite tidak membutuhkan tempat bagi persistence storage
Performance
Read and write operations pada persistence storage biasanya membutuhkan waktu yang lebih lama daripada disimpan dalam volatile memory
Oleh karena itu, disarankan untuk menggunakan thread terpisah untuk mengakses persistance storage
Caching frequently yang digunakan untuk membaca dan menuliskan data dari persistence storage ke vollatile memori dapat membantu meningkatkan performance
Exceptions
InvalidRecordIDExceptionMenunjukkan bahwa sebuah operation tidak dapat diselesaikan karena record ID yang tidak benar
RecordStoreExceptionMenunjukkan general exception yang mungkin hadir dalam record store operation
RecordStoreFullExceptionMenunjukkan record operation tidak dapat diselesaikan karena record store system sudah penuh
Exceptions
RecordStoreNotFoundExceptionMenunjukkan bahwa record store operation tidak dapat diselesaikan karena record store-nya tidak diketemukan
RecordStoreNotOpenExceptionMenunjukkan bahwa record store operation bekerja pada record store yang sedang ditutup
Persistence
Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Record Store
Sebuah record store merupakan collection of records
Record Id didalam Record Store adalah unik
Record Id secara otomatis dibangkitkan secara otomatis pada saat record diciptakan dan bertindak sebagai index atau primary key
Record ID akan diberikan secara sequential dimana record ID pertamanya adalah 1
Apabila record dihapus, maka record ID-nya tidak akan digunakan kembali
Record Store
Record ID Array of bytes
1 Data of record #1
2 Data of record #2
3 Data of record #3
5 Data of record #5
Record Store
MIDlets dapat membuat lebih dari sebuah record store
Nama dari record store adalah unik didalam MIDlet Suite
Nama dari Record store adalah case sensitive
Panjang maksimum dari Record Store adalah 32 karakter
Pada saat sebuah MIDlet suite dihapus dari device, semua record store yak terkoneksi dengan MIDlets didalam suite juga dihapus.
Version
Record stores memiliki informasi mengenai version Setiap kali record dimodifikasi, version dari record store tersebut juga
bertambah
Method getVersion() akan mengembalikan version dari sebuah record store
Timestamp
Record stores memiliki informasi mengenai timestamp
Timestamp akan menentukan kapan record tersebut dimodifikasi terakhir
Method getLastModified() dari class RecordStore akan mengembalikan timestamp dengan format hampir sama dengan System.getTimeInMillis() (long).
Creating Record Stores
static RecordStore openRecordStore(String recordStoreName,boolean createIfNecessary)
static RecordStore openRecordStore(String recordStoreName,boolean createIfNecessary, int authmode,boolean writable)
static RecordStore openRecordStore(String recordStoreName,String vendorName, String suiteName)
Record Store
Jika createIfNecessary di-set menjadi true, dan belum ditemukan Record Store, maka Record Store secara otomatis akan dibuat
Jika createIfNecessary di-set menjadi false dan Record Store tidak ditemukan, maka terjadi RecordStoreNotFoundException
Authmode parameter bisa berupa RecordStore.AUTHMODE_PRIVATE atau RecordStore.AUTHMODE_ANY.
Record Store
Menggunakan AUTHMODE_PRIVATE menyebabkan Record Store hanya dapat diakses oleh MIDlet suite yang menjadi pemilik dari MIDlet
Mengubah setting authmode ke AUTHMODE_ANY menjadikan Record Store dapat diakses oleh ANY MIDlet.
Access mode dispesifikasikan dengan boolean parameter writable.
Supaya MIDlet yang lain (diluar sebuah MIDlet suite) dapat menuliskan juga kepada record store tersebut, parameter ini harus di-set true
Record Store
Menggunakan bentuk pertama dari method openRecordStore() menyebabkan record store hanya bisa diakses oleh MIDlet didalam suite yang sama (authmode di-set ke AUTHMODE_PRIVATE).
Untuk membuka sebuah Record Store dari MIDlet suite yang berbeda, bentuk ketiga dari openRecordStore harus digunakan. Anda harus mengetahui nama vendor dan nama MIDlet suite-nya.
Jika Record Store sudah dibuka, maka method ini akan memberikan reference kepada record store
System akan tetap mengingat berapa kali record store akan dibuka, dimana tiap record store harus ditutup sesuai dengan berapa kali ia sudah dibuka
Menambah Record
Method addRecord akan menciptakan sebuah record baru pada record store dan akan mengembalikan record ID
Record akan dibuat, sebelum pengembalian record ID
int addRecord(byte[] data, int offset, int numBytes)
Retrieving Records
byte[] getRecord(int recordId)
int getRecord(int recordId, byte[] buffer,int offset)
int getRecordSize(int recordId)
•Bentuk pertama dari record adalah mengembalikan copy dari data store sesuai dengan record ID
•Bentuk kedua akan meng-copy data sesuai dengan array byte yang telah disediakanPada saat menggunakan bentuk kedua, byte array harus dialokasikan sebelumnya. Jika ukuran dari record lebih besar daripada paramater maka terjadi ArrayIndexOutOfBoundsException.
•Anda dapat menggunakan method getRecordSize untuk mengetahui berapa besar record yang hendak Anda baca.
Update Records
Anda tidak dapat memodifikasi hanya sebagian data
Jika Anda ingin memodifikasi record, Anda harus :
● Membaca record dengan getRecord()
● Meng-update record dalam memori
● Memanggil setRecord untuk menulis data yang telah diupdate ke record
void setRecord(int recordId, byte[] newData,int offset, int numBytes)
Menghapus Records
Pada saat sebuah record dihapus. Maka record ID tidak akan digunakan kembali pada saat Anda menggunakan addRecord untuk menambah data. Hal ini berarti, akan ada gap didalam record
Oleh karena itu, tidak disarankan untuk menggunakan increment counter untuk membaca seluruh records dalam record store
Gunakan Record Enumerator untuk melihat semua list record dalam record store
void deleteRecord(int recordId)
Menutup Record Store
Memanggil closeRecordStore() tidak akan menutup keseluruhan record store. Seluruh record store akan tertutup sampai ia dipanggil dengan jumlah yang sama dengan pemanggilan openRecordStore() untuk record store tertentu
Sistem akan menghitung berapa banyak record store dibuka.
Memanggil closeRecordStore lebih dari seberapa banyak ia dibuka akan menyebabkan RecordStoreNotOpen Exception.
void closeRecordStore()
Contoh Kode
// Membuat Record Store dengan nama "RmsExample1"recStore = RecordStore.openRecordStore("RmsExample1", true);
// Load content kedalam record storefor (int recId=1; recId<=recStore.getNumRecords(); recId++){ // getRecord return panjang dari record recLength = recStore.getRecord(recId, data, 0); // Convert dari byte array ke String String item = new String(data, 0, recLength); ...
}
Contoh Kode
...// String yang akan diletakkan kedalam recordString newItem = "Record #" + recStore.getNextRecordID(); // Convert String kedalam byte arraybyte[] bytes = newItem.getBytes(); // Tambahkan kedalam record storerecStore.addRecord(bytes, 0, bytes.length);
Contoh Kode
String[] storeNames = RecordStore.listRecordStores();System.out.println("Record Stores for this MIDlet suite:");
for (int i=0; storeNames!=null && i<storeNames.length; i++) { System.out.println(storeNames[i]);}
Java Primitives
Sejauh ini, data yang telah ditulis dan dibaca dari record store adalah String CLDC memiliki standard class untuk memanipulasi java primitif Class-class primitif tersebut berasal dari Java 2 Platform, Standard Edition (J2SE). Anda dapat menuliskan Java primitif dengan mengkombinasikan antara
ByteArrayOutputStream dan DataOutputStream Untuk pembacaan primitives (int, long, short, string, boolean, etc) juga dapat
dilakukan dengan menggunakan ByteArrayInputStream dan DataInputStream.
Java Primitives
ByteArrayOutputStream out = new ByteArrayOutputStream();DataOutputStream dOut = new DataOutputStream(out);
dOut.writeInt(recStore.getNextRecordID() * recStore.getNextRecordID());
dOut.writeUTF("Record #" + recStore.getNextRecordID());
byte[] bytes = out.toByteArray();
recStore.addRecord(bytes, 0, bytes.length);...
Java Primitives
// Dapatkan record selanjutnyabyte[] recBytes = enumerator.nextRecord(); ByteArrayInputStream in = new ByteArrayInputStream(recBytes);DataInputStream dIn = new DataInputStream(in);
int count = dIn.readInt();
String item = dIn.readUTF();
Persistence
The Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Record Enumeration Mengakses Record Store dengan menggunakan incrementing index dianggap tidak efisien
Record yang sudah dihapus, seharusnya tidak dibaca lagi karena ID-nya sudah tidak lagi digunakan.
Dengan menggunakan record enumerator akan menyelesaikan permasalahan dalam mengenali record yang sudah dihapus.
Anda juga dapat mengurutkan enumerator dengan menggunakan method comparator
Anda juga dapat menggunakan filter method untuk mengabaikan record yang tidak berguna bagi Anda.
Record Enumeration
Method edumerateRecords() akan mengembalikan enumeration dari semua record yang telah disimpan
Anda diharapkan menggunakan hal ini untuk mengenali setiap record didalam record store.
Cara termudah untuk mengimplementasikan method enumerateRecords() adalah dengan menggunakan null pada filter dan comparator.
RecordEnumeration enumerateRecords(RecordFilter filter,RecordComparator comparator,boolean keepUpdated)
Record Enumeration
recStore = RecordStore.openRecordStore( "RmsExample2", true); // Load contents dari Record Store
RecordEnumeration enumerator = recStore.enumerateRecords(null, null, false); while (enumerator.hasNextElement()){
// Dapatkan record selanjutnya, convert to String
String item = new String(enumerator.nextRecord()); // Lakukan sesuatu dengan record
Persistence
The Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Record Comparator
Urut-urutan dari sebuah enumeration dapat ditentukan dengan menggunakan Record Comparator. Sebuah Record Comparator akan diparsing pada sebuah method enumerateRecords(). Jika Anda ingin untuk memperpendek sebuah enumeration, Anda harus mendefinisikan sebuah comparator dan memparsing method tersebut sebagai parameter kedua pada enumerateRecords
Untuk menciptakan sebuah Record Comparator, Anda harus meng-implement interface Record Comparator
Record Comparator
Method compare akan mengembalikan, RecordComparator.FOLLOWS atau RecordComparator.PRECEDES jika rec1 follows atau precedes rec2 secara berurutan
RecordComparator.EQUIVALENT akan dikembalikan jika rec1
equivalent dengan rec2 pada urutan tertentu
int compare(byte[] rec1, byte[] rec2)
Record Comparator
// Sort secara alpabheticalclass AlphaOrder implements RecordComparator { public int compare(byte[] rec1, byte[] rec2){ String record1 = new String(rec1).toUpperCase();
String record2 = new String(rec2).toUpperCase();
if (record1.compareTo(record2) < 0){ return(PRECEDES); } else { if (record1.compareTo(record2) > 0){ return(FOLLOWS); } else { return(EQUIVALENT); }...
Record Comparator
// Menciptakan enumeration secara alphabeticRecordEnumeration enumerator = recStore.enumerateRecords(null, new AlphaOrder(), false);
...
Persistence
The Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Record Filter
Semua contoh yang telah kita pelajari, hanyalah membaca keseluruhan record dari record store
Kita dapat menggunakan filter untuk mendapatkan record tertentu yang kita inginkan
Method match() digunakan untuk menentukan target record
Ia akan mengembalikan true, jika record sesuai dengan kriteria Anda, atau return false, jika sebaliknya
boolean matches(byte[] candidate)
Record Filter
public boolean matches(byte[] candidate){ boolean isaMatch = false; try { ByteArrayInputStream bin = new ByteArrayInputStream(candidate); DataInputStream dIn = new DataInputStream(bin); int count = dIn.readInt(); String item = dIn.readUTF();
Record Filter
// return hanya record yang diakhiri dengan 0 if (item.endsWith("0")){ isaMatch = true; } else { isaMatch = false; } } catch (Exception e){ items.append(e.toString(), null); } return(isaMatch);}
Persistence
The Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener
Record Listener
Record listeners dapat didaftarkan pada record store Sebuah record listener adalah sebuah object yang akan dipanggil apabila record ditambah,
update, atau dihapus dari record store
Record listener harus meng-implement interface RecordListener
Record listeners didaftarkan pada record store menggunakan method addRecordListener()
Record Listener
Pada saat sebuah record store ditutup, semua record listener yang terkoneksi dengan record store juga akan dihapus
Pemanggilan deleteRecordStore() tidak akan menyebabkan pemanggilan recordDeleted()
void recordAdded(RecordStore recordStore, int recordId) Called when a record has been added to a record store.
void recordChanged(RecordStore recordStore, int recordId) Called after a record in a record store has been changed.
void recordDeleted(RecordStore recordStore, int recordId) Called after a record has been deleted from a record store.
Kesimpulan
Record Management System
Record Stores
Record Enumeration
Record Comparator
Record Filter
Record Listener