Blackberry SDK 5.0 版本支持三種存儲方式:
- RMS - Record Store
- PersistentStore - persistent store for RIMlet
- SQL Lite for RIMlet
RMS方式的存儲是基於byte數組的存儲,對象需要先序列化,再存儲。SQL Lite是數據庫方式存儲,支持SQL語句,這是5.0 SDK的新特性。Blackberry最成熟,最流行的存儲方式是PersistentStore,可以直接存儲對象。本文詳細介紹PersistentStore的方式。
PersistentStore存儲對數據類型和對象的要求:
- 被存儲對象只包含基本數據類型 - int, String, long, boolean, byte, 等等
- 被存儲類必須要執行 Persistable 接口
PersistentStore以Key-Value pair的方式進行數據存儲,key必須是一個long值,value的類型是Object. 下面來看一個例子:
1. 創建存儲數據類,比如class MyData:
public class MyData implements Persistable{
private String m_userName;
private String m_company;
private String m_title;
private int m_age;
public MyData(){}
public void setUserName(String userName){
m_userName = userName;
}
public String getUserName(){
return m_userName;
}
public void setCompany(String company){
m_company = company;
}
public String getCompany(){
return m_company;
}
public void setTitle(String title){
m_title = title;
}
public String getTitle(){
return m_title;
}
public void setAge(int age){
m_age = age;
}
public int getAge(){
return m_age;
}
}
注意的是MyData類執行了Persistable接口,這個接口沒有任何要執行的函數。MyData的instance variable都是基本類型,也可以有方法。
2. 存儲數據
public static final long ID = 0x5d8a91784555e0f8L;
public void saveData(){
if (myData == null){
myData = new MyData();
}
myData.setUserName("Protoss");
myData.setCompany("Blizzard");
myData.setTitle("Manager");
myData.setAge(26);
if (dataStore == null){
dataStore = PersistentStore.getPersistentObject(ID);
}
synchronized(dataStore){
if (dataStore.getContents() == null){
dataStore.setContents(myData);
dataStore.commit();
}
}
}
PersistentStore是key-value pair的存儲,需要一個ID,對應一個PersistentObject,存取數據時都要用到,一個ID只對應一個PersistentObject。存儲第一步需要從PersistentStore中用ID獲取PersistentObject,再調用PersistentObject.setContents(Object)接口填入存儲對象,這步其實還沒有保存數據,需要調用PersistentObject.commit()保存數據。
3. 獲取數據
public static final long ID = 0x5d8a91784555e0f8L;
public void recoverDataFromStore(){
if (dataStore == null){
dataStore = PersistentStore.getPersistentObject(ID);
}
synchronized(dataStore){
if (dataStore.getContents() != null){
myData = (MyData) dataStore.getContents();
}
}
if (myData != null){
userNameField.setText(myData.getUserName());
companyField.setText(myData.getCompany());
titleField.setText(myData.getTitle());
ageField.setText(myData.getAge()+"");
}
}
獲取數據第一步用ID獲取對應的持久對象PersistentObject,在調用PersistentObject.getContents()獲取數據對象,獲取的對象類爲Object,需要轉換成實際的類型,比如 myData = (MyData) dataStore.getContents()。
如下是PersistentStore的完整例子代碼,可以拷貝到Eclipse裏運行:
import net.rim.device.api.ui.UiApplication;
public class MyApp extends UiApplication{
public static void main(String[] args){
MyApp app = new MyApp();
app.enterEventDispatcher();
}
public MyApp(){
MyScreen myScreen = new MyScreen();
pushScreen(myScreen);
}
}
import net.rim.device.api.util.Persistable;
public class MyData implements Persistable{
private String m_userName;
private String m_company;
private String m_title;
private int m_age;
public MyData(){}
public void setUserName(String userName){
m_userName = userName;
}
public String getUserName(){
return m_userName;
}
public void setCompany(String company){
m_company = company;
}
public String getCompany(){
return m_company;
}
public void setTitle(String title){
m_title = title;
}
public String getTitle(){
return m_title;
}
public void setAge(int age){
m_age = age;
}
public int getAge(){
return m_age;
}
}
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class MyScreen extends MainScreen implements FieldChangeListener{
public static final long ID = 0x5d8a91784555e0f8L;
private PersistentObject dataStore;
private BasicEditField userNameField;
private BasicEditField companyField;
private BasicEditField titleField;
private BasicEditField ageField;
private ButtonField saveButton;
private MyData myData;
public MyScreen(){
super();
setTitle("Persist Data Test");
initialize();
addToWindow();
recoverDataFromStore();
}
private void initialize(){
userNameField = new BasicEditField("User Name: ", "", 20, BasicEditField.FILTER_DEFAULT);
companyField = new BasicEditField("Company Name: ", "", 20, BasicEditField.FILTER_DEFAULT);
titleField = new BasicEditField("Title: ", "", 20, BasicEditField.FILTER_DEFAULT);
ageField = new BasicEditField("Age: ", "", 20, BasicEditField.FILTER_NUMERIC);
saveButton = new ButtonField("save");
saveButton.setChangeListener(this);
}
private void addToWindow(){
add(userNameField);
add(titleField);
add(companyField);
add(ageField);
add(saveButton);
}
public void saveData(){
if (myData == null){
myData = new MyData();
}
myData.setUserName(userNameField.getText());
myData.setCompany(companyField.getText());
myData.setTitle(titleField.getText());
myData.setAge(Integer.valueOf(ageField.getText()).intValue());
if (dataStore == null){
dataStore = PersistentStore.getPersistentObject(ID);
}
synchronized(dataStore){
if (dataStore.getContents() == null){
dataStore.setContents(myData);
dataStore.commit();
}
}
}
public void recoverDataFromStore(){
if (dataStore == null){
dataStore = PersistentStore.getPersistentObject(ID);
}
synchronized(dataStore){
if (dataStore.getContents() != null){
myData = (MyData) dataStore.getContents();
}
}
if (myData != null){
userNameField.setText(myData.getUserName());
companyField.setText(myData.getCompany());
titleField.setText(myData.getTitle());
ageField.setText(myData.getAge()+"");
}
}
public void fieldChanged(Field field, int context) {
if (field == saveButton){
saveData();
}
}
}