Автор неизвестен - Платформа J2Me
MIDP поддерживает постоянное хранение данных приложения с помощью системы управления записями (Record Management System (RMS)). Пакет javax.microedition.rms определяет программные интерфейсы приложения, поддерживающие постоянное хранение данных, которые содержит этот пакет.
Поддержка постоянного хранения устройством
Каждое соответствующее требованиям MIDP устройство поддерживает выделенную область памяти для постоянного хранения данных приложения. Данные MID-лета, хранящиеся там, постоянно существуют при множестве инициализаций приложения, которое их использует. Как физическое местоположение, так и размер хранилища данных зависят от устройства.
RMS API извлекает подробную информацию об области хранения устройства и доступе к этой информации, а также предоставляет единообразный механизм для создания, уничтожения и изменения данных. Это гарантирует переносимость MID-летов на различные устройства.
Модель хранения данных RMS
RMS поддерживает создание множества хранилищ записей, показанных на рисунке 7.1, и управление ими. Хранилище записей — это база данных, основным понятием которой является запись. Каждое хранилище записей содержит ноль или больше записей. Название хранилища записей чувствительно к регистру и может состоять максимум из 32 знаков уникода. Хранилище записей создается МШ-летом.
Рисунок 7.1. RMS состоит из одного или нескольких хранилищ записей, каждое из которых содержит ноль или более записей, представляющих собой массив байтов
MID-леты в пределах одного набора MID-летов могут совместно использовать хранилища записей друг друга. Набор MID-летов определяет пространство имен для хранилищ записей, хранилище записей должно иметь уникальное в пределах набора MID-летов имя. Однако в различных MID-летах могут использоваться одинаковые имена, MID-леты могут составлять список имен всех хранилищ записей, доступных им. Они также могут определять размер свободного места, доступного для хранения данных.
В этой связи вы должны знать, что когда все MID-леты в наборе MID-летов удаляются с устройства, AMS устройства удаляет все хранилища записей в пространстве имен набора MID-летов. Все данные постоянного хранения будут потеряны. По этой причине вы должны обдумать при разработке приложения включение предупреждения или подтверждения, требующего, чтобы пользователи подтвердили, что они поняли потенциальную угрозу потери данных при удалении приложений! Приложения могут также включать механизм резервного копирования записей хранилища данных в другое место. Это может потребовать поддержки со стороны сервера, задача, которую я описываю в главе 11.
RMS определяет следующие абстрактные операции для отдельного хранилища записей:
Добавление записи. Удаление записи. Изменение записи. Просмотр (извлечение) записи. Составление списка всех записей.
Записи однозначно идентифицируются с помощью ID записи, который является единственным поддерживаемым важнейшим ключевым типом. Тип ID всех записей является встроенным типом Java int. RMS не поддерживает свойств — таких, как таблицы, строки, столбцы, типы данных и так далее, — которые присутствуют в реляционных базах данных.
Записи
Запись является массивом байтов типа byte []. RMS не поддерживает описание или форматирование полей записи. Ваше приложение должно определять элементы данных записи и их формат.
Читатель записи поэтому должен знать формат, который использовался при ее создании. Поскольку запись является просто массивом байтов, приложения должны преобразовывать данные из произвольных типов в байты при создании записей, а затем преобразовывать их из байтов в типы при чтении данных.
Пример приложения
В остальной части этой главы описываются частные подробности RMS с помощью следующего примера, использующего базовые свойства RMS. Этот пример является простой адресной книгой, которая хранит имена и номера телефонов.
Многие из примеров имеют дело с созданием организации и структуры приложений MIDP. Большинство протекающих операций RMS ограничены одним классом. В этом примере вы можете видеть, как включать использование постоянного хранения в приложение, которое вы, вероятно, найдете на настоящем мобильном устройстве.
Конечно, вы можете создать и исполнить исходный код, приведенный в этой главе, для получения представления о том, как приложение продвигается вперед по различным экранам. Я оставляю это на ваше усмотрение вместо того, чтобы показывать вам здесь изображения всех этих экранов.
Следующие файлы включены в адресную книгу, описанную в данном примере:
— AddScreen.java;
— AddressBook.java;
— AddressBookMain.java;
— DeleteAllConfirmationScreen.java;
— PersistenceDemo.java;
— RecordList.java;
— SearchResultScreen.java;
— SearchScreen.java.
Подробные листинги этих файлов можно найти на Web-сайте «Prentice-Hall» по адресу http://www.phptr.com. Файл PersistenceDemo.java определяет MID-лет, который представляет меню, содержащее приложение адресной книги. Файл AddressBookMain.java определяет точку входа в приложение адресной книги.
В листинге 7.1 показан полный исходный код класса AddressBook.java. Этот класс извлекает подробную информацию о вызовах RMS API из остальной части МID-лета. При инициализации MID-лета он создает экземпляр класса AddressBook, который, в свою очередь, открывает хранилище записей с именем addressbook.
Листинг 7.1. Класс AddressBook позволяет приложению получать доступ к хранилищу записей
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordFilter;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;
import Java.io.ByteArrayInputStream/
import java.io.ByteArrayOutputStream;
import Java.io.DatalnputStream;
import java.io.DataOutputStream;
import Java.io.lOException;
/**
Этот класс внедряет простую адресную книгу с целью демонстрации.
В нем хранятся записи, состоящие из полей имени String и номера телефона String.
Этот класс определяет два внутренних класса, один является блоком сравнения записей, а второй фильтром записей, используемым при извлечении записей.
*/
public class AddressBook
private static final String RECORD_STORE_NAME = «address-book»;
private RecordStore recordStore;
public AddressBook () throws RecordStoreException
super!);
recordStore = RecordStore.openRecordStore(RECORD_STORE_NAME, true);
{
void close() throws RecordStoreException
{
try
{
recordStore.closeRecordStore();
}
catch (RecordStoreNotOpenException rsno)
{
}
}
/*
Получает хранилище записей, используемое этим объектом.
@возвращаем ссылку на RecordStore, используемый этим объектом.
public RecordStore getRecordStore()
}
return recordStore;
/**
Добавляет указанную запись в хранилище записей данной адресной книги.
@param name имя входа было добавлено.
@parara phone телефонный номер для входа был добавлен.
@сбрасывает RecordStoreException, если есть проблемы с добавлением записи.
public void addRecord(String name, String phone)
throws RecordStoreException
}
ByteArrayOutputStreara baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try
dos.writeUTF(name); dos.writeUTF(phone);
}
catch (lOException ioe)
{
ioe.printStackTrace();
)
int id =
recordstore.addRecord(baos.toByteArray(), 0,
baos.toByteArrayO.lengthy-System, out. println ("Record id = " + id);
}
/**
RecordEnumerator, упорядочивающий записи в лексикографическом порядке по полям имен записей.
*/
RecordEnumeration getMatchesByNarae(String matchKey)
throws RecordStoreNotOpenException
(
MacchAllNaraesFilter filter =
new MatchAllNamesFilter(matchKey);
AlphabeticalOrdering comparator =
new AlphabeticalOrdering();
return recordStore.enuraerateRecords(filter,
comparator, false);
}
/**
RecordFilter, устанавливающий совпадение, если имя варианта (первое поле в записи варианта)!) точно соответствует имени элемента списка или 2) если строка имени элемента списка начинается с имени варианта. Возвращает значение true, ее установлено соответствие, false — в ином случае.
*/
class MatchAllNamesFilter implements RecordFilter
{
String requestString;
public MatchAllNamesFilter(String matchKey);
requestString = matchKey;
}
public boolean matches(byte [] candidate)
{
ByteArraylnputStream bais =
new ByteArraylnputStream(candidate);
DatalnputStream dis = new DatalnputStream(bais);
Siring name = null;
try
}
name = dis.readUTF();
if (name.indexOf(requestString) == 0)
return true;
else
return false;
}
catch (lOException ioe)
{
ioe.printStackTrace!);
return true;
}
}
/**
Этот внутренний класс реализует RecordCornparator, чья политика Заключается в выполнении сортировки по алфавиту.
*/
class AlphabeticalOrdering implements RecordCoraparator
}
Конструктор.