Monday, November 9, 2009

J2ME - Record Management System (RMS)

Persistent storage is a non-volatile place for storing the state of objects. For some applications, you might need objects to exist even after the application that created those objects quits. Without persistent storage, objects and their states are destroyed when an application closes. If you save objects to persistent storage, their lifetime is longer than the program that created them, and later you can read their state and continue to work with them.

The MIDP provides a mechanism for MIDlets to persistently store data and retrieve it later. This mechanism is a simple record-oriented database called the Record Management System (RMS). A MIDP database (or a record store) consists of a collection of records that remain persistent after the MIDlet exits. When you invoke the MIDlet again, it can retrieve data from the persistent record store.


The J2ME record management system (RMS) provides a mechanism through which MIDlets can persistently store data and retrieve it later. In a record oriented approach, J2ME RMS comprises multiple record stores.

To use the RMS, import the javax.microedition.rms package.

Each record store can be visualized as a collection of records, which will remain persistent across multiple invocations of the MIDlet. The device platform is responsible for making its best effort to maintain the integrity of the MIDlet's record stores throughout the normal use of the platform, including reboots, battery changes, etc.

Record stores (binary files) are platform-dependent because they are created in platform-dependent locations. MIDlets within a single application (a MIDlet suite) can create multiple record stores (database files) with different names. The RMS APIs provide the following functionality:

  • Allow MIDlets to manipulate (add and remove) records within a record store.

  • Allow MIDlets in the same application to share records (access one another's record store directly).

  • Do not provide a mechanism for sharing records between MIDlets in different applications.

Record store implementations ensure that all individual record store operations are atomic, synchronous, and serialized, so no corruption of data will occur with multiple accesses. The record store is timestamped to denote the last time it was modified. The record store also maintains a version, which is an integer that is incremented for each operation that modifies the contents of the record store. Versions and timestamps are useful for synchronization purposes.

When a MIDlet uses multiple threads to access a record store, it is the MIDlet's responsibility to coordinate this access; if it fails to do so, unintended consequences may result. Similarly, if a platform performs a synchronization of a record store with multiple threads trying to access the record store simultaneously, it is the platform's responsibility to enforce exclusive access to the record store between the MIDlet and its synchronization engine.

Each record in a record store is an array of bytes and has a unique integer identifier.

Record Id Data

1 Array of Bytes

2 Array of Bytes

3 Array of Bytes

.. ....

.. ....

Record stores are identified by name. A name may consist of up to 32 characters, and all characters are case sensitive. No two record stores within a MIDlet suite (that is, a collection of one or more MIDlets packaged together) may contain the same name.

Each record store has a version number as well as a date/time stamp. Both values are updated whenever a record is added, replaced, or deleted.

Creating a Record Store

No constructor exists for creating a record store. Here, we use a set of three dual-purpose methods to create and/or open record stores.

RecordStore openRecordStore(String recordStoreName,boolean createIfNecessary)

RecordStore openRecordStore(String recordStoreName,boolean createIfNecessary,int authmode,boolean writable)
RecordStore openRecordStore(String recordStoreName,String vendorName,String suiteName)

The RecordStore API

In this API you will find the methods which enables you to work with a record store. These range from adding, deleting, and replacing record contents to enumerating through a record store.

Following are the list of methods:

void closeRecordStore()

void deleteRecordStore(String recordStoreName)
String[] listRecordStores()
int addRecord(byte[] data, int offset, int numBytes)
void setRecord(int recordId, byte[] newData, int offset, int numBytes)
void deleteRecord (int recordId)
byte[] getRecord (int recordId)
int getRecord (int recordId, byte[] buffer, int offset)
int getRecordSize (int recordId)
int getNextRecordID()
int getNumRecords()
long getLastModified()
int getVersion()
String getName()
int getSize()
int getSizeAvailable()
RecordEnumeration enumerateRecords(RecordFilter filter,RecordComparator comparator,boolean keepUpdated)
void addRecordListener (RecordListener listener)
void removeRecordListener (RecordListener listener)
void setMode(int authmode, boolean writable)

The RecordEnumeration API

The primary benefits of incorporating a record enumerator into your code is that it includes options

for searching the record store,and for retrieving records in sorted order.
Another point that we've
been traversing the record store with a simple for loop. Although this technique has been sufficient
to our needs so far,we'll see in this section what happens when we extend our code to include a
record enumerator. One of the primary benefits of incorporating a record enumerator into your code
is that it includes options for searching the record store, and for retrieving records insorted order.

Method available in RecordEnumeration API as follows:

int numRecords()
byte[] nextRecord()
int nextRecordId()
byte[] previousRecord()
int previousRecordId()
boolean hasNextElement()
boolean hasPreviousElement()
void keepUpdated(boolean keepUpdated)
boolean isKeptUpdated()
void rebuild()
void reset()
void destroy()

The RecordComparator API

The RecordEnumeration API provides the foundation for working with enumerations, allowing us to cycle through entries in the RMS. But it's the RecordComparator interface that lets us actually retrieve records from the record store in sorted order.

The RecordComparator API consists of one method and three pre-defined return values. The sole method in this interface accepts two parameters, and both are byte arrays.
Methods/Static Data Fields for RecordComparator API


int compare(byte[] rec1, byte[] rec2)

static int EQUIVALENT
static int FOLLOWS
static int PRECEDES

The RecordFilter API

Sorting with a comparator is one option when working with an enumerator, searching with a filter is the other. A minor difference between a comparator and a filter is that a comparator returns the entire record store in sorted order, whereas a filter returns only those records that match a specified criteria. If you apply both a comparator and a filter, records that match the search criteria will be returned in sorted order.

Like the RecordComparator, the RecordFilter is implemented by the addition of a single method, matches(), to the enumerator code. The enumerator calls thematches() method for each record in the store. Based on the boolean return value, the record either becomes a member of the result set or is tossed aside as a record that does not meet the search criteria.

Method for RecordFilter API

boolean matches(byte[] candidate)


















2 comments:

  1. Record Management System is very important aspect when it comes to persistent storage.It is useful cause with the use of RMS we can store the record and retrieve it later.RMS is very well defined in this post so take a look over this information.Thanks
    records management

    ReplyDelete