国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

探索J2ME:使用記錄管理系統

2019-11-18 12:45:58
字體:
來源:轉載
供稿:網友

  歡迎回到我的J2ME系列開發文章。假如你已經從頭開始學習這一系列文章,你就會想起上次我們為了可以實現同時編輯現有條目和新增條目的功能而修改了EXPensesApp應用程序的MIDlet組件。ExpenseApp不能在運行過程中存儲新增的開銷條目,這使得它的作用受到限制。
  在本文中,我們將通過MIDP的記錄治理系統(RMS)來為ExpensesApp MIDlet組件創建一個記錄存儲器來解決上述問題。我們將會把ExpensesApp增強到記錄庫的程度,這將使得該應用程序——最終在理論上——是有用的。
  第一和第二篇文章
  
  假如你決心加入學習本系列文章的行列,請確保你已經學習了本系列的前兩篇文章:
  
  探索J2ME:構建開銷追蹤系統
  探索J2ME:創建開銷細節表單
  
  記錄存了些什么?
  MIDP規范要求運行平臺提供某種穩固的存儲手段(通過非揮發性的存儲器,即掉電后存儲的信息不會丟失的存儲器)。RMS(記錄治理系統)治理記錄庫,記錄庫即為二進制平面文件(flat file,由不包括重復組的一組同類型記錄構成的文件)。記錄庫中的每一段數據都涉及到某一個記錄,它還擁有一個由數字組成的記錄ID號,ID在整個記錄庫中是互不重復的。每一個記錄庫的名字在創建它的MIDlet組件中也是互不相同的,MIDlet只可以訪問它自己或同一組件中其它MIDlet所創建的記錄庫。當從設備(device)中刪除MIDlet組件時,所有與MIDlet組件相關的記錄庫也全部被刪除。
  javax.microedition.rms軟件包包含了RecordStore類,RecordStore類提供了訪問記錄庫中的數據的初步方法。該軟件包還包含了對記錄庫中的記錄進行排序、搜索的其它類。在本文中,為了簡明起見,我將集中介紹RecordStore類,其它的類將在以后介紹。
  RecordStore類的運行
  
  RecordStore類的運行過程很簡單明了。你可以用靜態RecordStore.openRecordStore方法打開一個已有的記錄庫,這會為這個指定名字的記錄庫返回一個RecordStore實例。假如你指定的記錄庫的名字不存在,該方法也可以創建一個以改名字命名的新的記錄庫(參見createIfNecessary參數)。使用getRecord方法你就可以通過記錄ID來得到ID對應的記錄。你還可以用addRecord和setRecord方法分別實現添加記錄和更新記錄的功能。當你完成了對記錄庫的操作,別忘了用closeRecordStore來關閉這個記錄庫。
  關于記錄ID的一個注釋:
  在Sun公司的標準實現(Sun’s reference implementation)中,給定記錄的ID號與它的插入次序是相同的。記錄庫中第一個插入的記錄以1為它的ID號,第二個插入的記錄以2為ID號,以此類推。盡管這聽起來似乎很方便,但是實際上并不總是如此。MIDP規范只要求每個記錄都有一個ID號——ID號是如何創建的問題則留給平臺的實現者。
  RecordStore類的絕大多數方法都可以拋出一個或者多個RecordStoreException類型的例外。例外的子類和它們對應的意義如下所示:
  
  InvalidRecordIDException例外,當某個被調用的方法涉及一個不存在的記錄ID號(當讀或者更新某個記錄時)或者記錄ID號無效(當添加記錄時)時,就會拋出InvalidRecordIDException例外。
  RecordStoreFullException例外,當RMS(記錄治理系統)的存儲器滿時,就會拋出該例外。例如,用OpenRecordStore來打開一個指定名字的記錄庫時,即使沒有更新記錄庫,它也有可能拋出RecordStoreFullException例外。
  RecordStoreNotFoundException例外,當某個被調用的方法涉及到一個不存在的的記錄庫時,就會拋出該例外。假如指定名字的記錄庫不存在,OpenRecordStore也可以創建擁有該名字的記錄庫。該例外也可能從一個希奇的地方拋出:CloseRecordStore方法。
  RecordStoreNotOpenException例外,假如你試圖訪問一個尚未被打開的記錄庫(用OpenRecordStore方法打開記錄庫)時,就會拋出該例外。
  最后,由于被處理的對象是二進制數據,記錄庫訪問方法(getRecord、addRecord和setRecord)均把記錄數據做為字節數組處理。你會發現——除非你有些喜歡被虐待——java.io軟件包的流處理類,如ByteArrayInputStream、ByteArrayOutputStream、 DataInputStream、和DataOutputStream,使用起來并不可靠。
  深入代碼
  
  你可以從這兒下載最新版本的ExpensesApp應用程序的代碼。在寫本文時,我起初只想修改ExpenseInfo類,但是RecordStore類是由一種古怪(quirky)的方法實現的,這使得這么做會難以置信得復雜。(在別的地方需要好幾個try嵌套語句)。結果,我對Expenses和DetailForm類也做了修改,從而簡化了整個過程。
  
  事實上,絕大多數RMS(記錄治理系統)都有類似的怪癖(quirk),把這些怪癖弄到一塊會阻礙你的開發進度。下面是一些我曾碰到的問題:不同的類中的功能類似的方法應該有同樣或者近似的名字,可是在RMS中不是這樣;一些方法的名字“名不副實”,會誤導你錯誤熟悉該方法的功能;還有一些方法會在編程者無法處理的情況下拋出例外。你會發現,假如你經常使用J2ME類,擁有一份MIDP的Java文檔,或者至少一個有方法提示(method PRompting)功能的編輯器是非凡值得的。
  
  看看代碼清單A,你會發現靜態方法ExpenseInfo.LoadExpenses為了從RecordStore對象中讀取數據而被修改了。當打開或者創建一個記錄庫后,我會遍歷庫中所有的記錄,把每個記錄中的數據提取到一個字節數組中,然后為每一個記錄創建一個新的ExpenseItem實例,并用一個Vector返回整套條目。ExpenseInfo.LoadExpenses現在拋出RecordStoreException例外,closeRecordStore本身也會拋出例外,因此改變(代碼)是不可避免的了,這樣,Expenses類的構造函數也需要加上一個try語句。
  
  我還用RMS的API來更新了ExpenseInfo.save和 ExpenseInfo.delete方法。你可以在代碼清單B中找到它們。這兩個方法通過檢查非零記錄ID(私有ExpenseID變量)來檢測記錄是否存在于當前實例中。假如通過方法save來保存一個新的開銷記錄,就會調用addRecord方法來把該記錄添加到記錄庫中。假如記錄已經存在,save方法就調用setRecord方法來更新對應的記錄。Delete方法工作過程與之類似,假如它的實例沒有記錄ID號就什么也不做(因為它還沒有被保存),假如記錄ID號(ExpenseID)非零,則調用deleteRecord方法來刪除對應記錄。
  
  還有進一步的工作需要完成
  我們已經讓ExpensesApp應用程序前進了一大步,但是尚未全部完成。現在它還存在下列問題:
  
  刪除函數還有錯誤(bug):在記錄庫文件的中部將會引發LoadExpenses,并拋出InvalidRecordIDException例外。因此,lsMain中的cmDelete命令不可靠。
  目前,開銷條目按輸入是到lsMain的順序來顯示的。假如按存儲其中的數據來排序顯示這些條目會比較有用。
  你能發現這些bug嗎?
  請你考慮這個練習。首先,去掉Expense類的構造函數中的注釋符,這樣就恢復了先前被注釋掉的刪除函數。然后運行ExpensesApp應用程序,并添加若干個新的開銷項目。接著,刪除你剛才輸入的第二個開銷項目,并關閉ExpensesApp。當你再次進入ExpensesApp就會捕捉到一個例外情況。想想這是為什么。
  在下一篇探索J2ME文章中,我將向你展示如何用RecordEnumeration類來解決上述兩個問題。祝你好運。
  
  本文的相關連接請點這里

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 文昌市| 灵寿县| 叶城县| 光山县| 龙泉市| 都江堰市| 盐源县| 景洪市| 丰镇市| 房产| 龙井市| 塔河县| 池州市| 天等县| 广安市| 惠来县| 纳雍县| 马尔康县| 淮滨县| 丹阳市| 宁蒗| 武山县| 老河口市| 松溪县| 彰化县| 滁州市| 浦北县| 五原县| 平山县| 澜沧| 遵义市| 宾阳县| 烟台市| 南昌县| 荃湾区| 明光市| 荆州市| 泸溪县| 泸溪县| 南江县| 潜江市|