亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        JAVA認(rèn)證:JavaME的RMS通用持久化框架

        字號:

        在寫JAVAME程序的時候,我們經(jīng)常需要保存一些數(shù)據(jù)到手機(jī)里面,也經(jīng)常希望能把對象也保存到手機(jī)里面,但是JAVAME里面沒有反射機(jī)制,也沒有java.io.Serializable接口,所以沒有序列化的機(jī)制,要保存對象的話,就得自己動手了。
            在JAVAME中,程序的數(shù)據(jù)保存的地方,無外乎兩種,一種是把數(shù)據(jù)保存在RMS里面,這是所有的JAVAME的手機(jī)都支持的,還有一種就是把數(shù)據(jù)保存在手機(jī)的文件系統(tǒng)里面,這個不是所有手機(jī)都能支持的,只有支持JSR075的手機(jī),才支持把數(shù)據(jù)保存在文件系統(tǒng)里面,并且如果你的程序沒有經(jīng)過簽名的話,你每次保存或者讀取,手機(jī)都會彈出惱人的提示,是否允許程序訪問文件系統(tǒng)。所在我一般都是把數(shù)據(jù)存在RMS里面,因?yàn)樽x寫RMS是安全的,并且也是不需要手機(jī)提示的。因?yàn)槲覀兊腞MS數(shù)據(jù)是存在一個特殊的地方。但是JAVAME的RMS功能非常底層,為了保存一些數(shù)據(jù),我們必須和 byte[]打交道,所以我就產(chǎn)生了,在此之前封裝一層自己的程序的想法,這樣封裝好以后,使用起來就非常方便了。只要實(shí)現(xiàn)了相關(guān)接口,就可以享受到比較易用的方法了。
            此框架總共包括了四個類,分別如下:Serializable類,它是一個接口,類似于JAVASE里面的Serializable接口,不同的就是,JAVASE里面的接口是一個空接口,只做標(biāo)記用的,而這里的這個接口是有方法需要實(shí)現(xiàn)的。
            Lazy類,它也是一個接口,它定義了一些方法,如果你的對象比較大,需要惰性加載的時候,可以實(shí)現(xiàn)此接口,并且此接口是Serializable接口的子類,也就是說實(shí)現(xiàn)了Lazy接口,你就相當(dāng)于實(shí)現(xiàn)了Serializable接口。
            RMSUtil類,此類是一個工具類,用于統(tǒng)一進(jìn)行RMS的相關(guān)操作,也是此框架的核心類。
            RecordFetcher類,也是一個接口,它繼承了RecordComparator, RecordFilter接口,在取數(shù)據(jù)的時候,需要用到它。
            好了,下面我們就開始看代碼吧。
            1 /*
            2 * To change this template, choose Tools | Templates
            3 * and open the template in the editor.
            4 */
            5 package com.hadeslee.mobile.rms;
            6
            7 import java.io.IOException;
            8
            9 /**
            10 * 一個可自己串行化的類所要實(shí)現(xiàn)的接口
            11 * @author hadeslee
            12 */
            13 public interface Serializable {
            14
            15 /**
            16 * 把自己編碼成字節(jié)數(shù)組的格式
            17 * @return 字節(jié)數(shù)組
            18 */
            19 public byte[] serialize() throws IOException;
            20
            21 /**
            22 * 把一個對象用此字節(jié)數(shù)組進(jìn)行重裝
            23 * @param data 字節(jié)數(shù)組
            24 */
            25 public void unSerialize(byte[] data) throws IOException;
            26
            27 /**
            28 * 設(shè)置此對象序列化后對應(yīng)的存儲對象的ID
            29 * @param id ID
            30 */
            31 public void setId(int id);
            32
            33 /**
            34 * 得到此對象序列化后的ID
            35 * 此方法唯有在反序列化后的對象上調(diào)用才有效
            36 * 如果一個對象是沒有序列化的,那么它的ID是-1;
            37 * @return ID
            38 */
            39 public int getId();
            40 }
            41
            1 /*
            2 * To change this template, choose Tools | Templates
            3 * and open the template in the editor.
            4 */
            5 package com.hadeslee.mobile.rms;
            6
            7 import java.io.IOException;
            8
            9 /**
            10 * 可以延遲加載的對象必須要實(shí)現(xiàn)的接口
            11 * @author binfeng.li
            12 */
            13 public interface Lazy extends Serializable {
            14
            15 /**
            16 * 實(shí)現(xiàn)此接口的類要實(shí)現(xiàn)的方法
            17 * 可以用于延遲加載某些屬性。比如
            18 * get("ImgData"),get("fullImage")..等等
            19 * 由于J2ME不支持注釋也不支持反射,所以只能以
            20 * 此種方法來進(jìn)行模擬了
            21 * 此方法是RMSUtil要存對象的時候調(diào)用的,這樣就可以把
            22 * 一個對象的不同部份存到不同的RMS里面去了
            23 * @param key 要得到的某性的鍵
            24 * @return 其對應(yīng)的值
            25 * @throws IOException
            26 */
            27 public byte[] getAttach(Object key)throws IOException;
            28
            29 /**
            30 * 當(dāng)把某個附屬的對象保存進(jìn)去以后,所要調(diào)用的
            31 * 方法,此方法告訴主體,它的那個附件被保存后
            32 * 在RMS里面對應(yīng)的ID是多少
            33 * @param key
            34 * @param id
            35 */
            36 public void savedAttach(Object key, int id);
            37
            38 /**
            39 * 得到此對象所支持的所有的key的數(shù)組
            40 * @return KEY的數(shù)組,不能為NULL
            41 */
            42 public Object[] getAttachKeys();
            43
            44 /**
            45 * 此對象的附屬對象所存的RMS的名字
            46 * @return RMS的名字
            47 */
            48 public String getNameOfAttachRMS();
            49 }
            50
            1 /*
            2 * To change this template, choose Tools | Templates
            3 * and open the template in the editor.
            4 */
            5 package com.hadeslee.mobile.rms;
            6
            7 import javax.microedition.rms.RecordComparator;
            8 import javax.microedition.rms.RecordFilter;
            9
            10 /**
            11 * 此類是一個繼承了兩個接口的接口,并且添加了自己
            12 * 的方法,自己的方法是用于通知數(shù)量以及開始取的位置
            13 * 只是為了方便于傳遞參數(shù)以及以后擴(kuò)展
            14 * @author binfeng.li
            15 */
            16 public interface RecordFetcher extends RecordComparator, RecordFilter {
            17
            18 /**
            19 * 從哪個下標(biāo)開始取
            20 * @return 下標(biāo)
            21 */
            22 public int getFromIndex();
            23
            24 /**
            25 * 最多取多少條記錄
            26 * @return 記錄
            27 */
            28 public int getMaxRecordSize();
            29 }
            30
            1 /*
            2 * To change this template, choose Tools | Templates
            3 * and open the template in the editor.
            4 */
            5 package com.hadeslee.mobile.rms;
            6
            7 import com.hadeslee.mobile.log.LogManager;
            8 import java.util.Enumeration;
            9 import java.util.Hashtable;
            10 import java.util.Vector;
            11 import javax.microedition.rms.RecordEnumeration;
            12 import javax.microedition.rms.RecordStore;
            13 import javax.microedition.rms.RecordStoreException;
            14
            15 /**
            16 * 一個專門用來操作RMS的工具類,通過這個類
            17 * 可以把RMS封裝起來,上層調(diào)用就更方便了
            18 * @author binfeng.li
            19 */20 public class RMSUtil {
            21
            22 /**
            23 * 用于緩存生命周期之內(nèi)的所有的RecordStore的表,當(dāng)MIDlet要退出的
            24 * 時候,調(diào)用此類的關(guān)閉方法,使RMS正確地被關(guān)閉
            25 */
            26 private static Hashtable rmsCache = new Hashtable();
            27
            28 private RMSUtil() {
            29 }
            30
            31 /**
            32 * 插入一個對象到一個RMS的數(shù)據(jù)庫里面,如果此數(shù)據(jù)庫不存在
            33 * 則自動創(chuàng)建一個對于MIDlet私有的數(shù)據(jù)庫。如果存在,則直接
            34 * 插在此數(shù)據(jù)庫的最后面
            35 * @param ser 要插入的數(shù)據(jù),必須是實(shí)現(xiàn)了Serializable接口的類
            36 * @return 是否插入成功
            37 */
            38 public static boolean insertObject(Serializable ser) {
            39 RecordStore rs = null;
            40 try {
            41 rs = getRecordStore(ser.getClass().getName());
            42 if (ser instanceof Lazy) {
            43 Lazy lazy = (Lazy) ser;
            44 insertAttachDatas(lazy);
            45 }
            46 byte[] data = ser.serialize();
            47 int id = rs.addRecord(data, 0, data.length);
            48 ser.setId(id);
            49 return true;
            50 } catch (Exception exe) {
            51 exe.printStackTrace();
            52 LogManager.error("RMSUtil.insertObject(),ser = " + ser + ",exe = " + exe);
            53 return false;
            54 }
            55 }
            56
            57 /**
            58 * 更新某個對象到RMS里面去,
            59 * @param ser 要更新的對象
            60 * @return 是否成功
            61 */
            62 public static boolean updateObject(Serializable ser) {
            63 RecordStore rs = null;
            64 try {
            65 rs = getRecordStore(ser.getClass().getName());
            66 byte[] data = ser.serialize();
            67 rs.setRecord(ser.getId(), data, 0, data.length);
            68 return true;
            69 } catch (Exception exe) {
            70 exe.printStackTrace();
            71 LogManager.error("RMSUtil.updateObject(),ser = " + ser + ",exe = " + exe);
            72 return false;
            73 }
            74 }
            75
            76 /**
            77 * 從RMS里面刪除某個對象
            78 * @param ser 要刪除的對象
            79 * @return 是否成功
            80 */
            81 public static boolean deleteObject(Serializable ser) {
            82 if (ser.getId() == -1) {
            83 return false;
            84 }
            85 RecordStore rs = null;
            86 try {
            87 rs = getRecordStore(ser.getClass().getName());
            88 int id = ser.getId();
            89 rs.deleteRecord(id);
            90 ser.setId(-1);
            91 return true;
            92 } catch (Exception exe) {
            93 exe.printStackTrace();
            94 LogManager.error("RMSUtil.deleteObject(),ser = " + ser + ",exe = " + exe);
            95 return false;
            96 }
            97 }
            98
            99 /**
            100 * 從某個數(shù)據(jù)庫里面讀取某個對象
            101 * @param id 此對象的ID
            102 * @param clz 對應(yīng)的類
            103 * @return 此對象,如果發(fā)生任何異常,則返回null
            104 */
            105 public static Serializable readObject(int id, Class clz) {
            106 RecordStore rs = null;
            107 try {
            108 rs = getRecordStore(clz.getName());
            109 byte[] data = rs.getRecord(id);
            110 Serializable ser = (Serializable) clz.newInstance();
            111 ser.unSerialize(data);
            112 ser.setId(id);
            113 return ser;
            114 } catch (Exception exe) {
            115 //如果讀取對象失敗,則可能是有東西被刪了或者版本不一樣,此時就應(yīng)該刪掉
            116 exe.printStackTrace();
            117 LogManager.error("RMSUtil.readObject(),id = " + id + ",Class = " + clz + ",exe= " + exe);
            118 if (rs != null) {
            119 try {
            120 rs.deleteRecord(id);
            121 } catch (Exception ex) {
            122 ex.printStackTrace();
            123 LogManager.error("RMSUtil.readObject$rs.deleteRecord(id),id = " + id + ",exe = " + ex);
            124 }
            125 }
            126 return null;
            127 }
            128 }
            129
            130 /**
            131 * 得到某個類存在RMS里面的總數(shù),這樣便于分段取
            132 * @param cls 類名
            133 * @return 有效記錄總數(shù)
            134 */  135 public static int getStoreSize(Class cls) {
            136 try {
            137 RecordStore rs = getRecordStore(cls.getName());
            138 return rs.getNumRecords();
            139 } catch (Exception exe) {
            140 exe.printStackTrace();
            141 LogManager.error("RMSUtil.getStoreSize(),Class = " + cls + ",exe = " + exe);
            142 return -1;
            143 }
            144 }
            145
            146 /**
            147 * 列出某個類的對象的集合,最多取多少個對象
            148 * @param cls 類名
            149 * @param from 從第幾個開始取
            150 * @param maxSize 最多取多少個對象
            151 * @return 取到的列表
            152 */
            153 public static Vector listObjects(Class cls, int from, int maxSize) {
            154 System.out.println("class="+cls);
            155 if (from < 0 || maxSize < 1) {
            156 throw new IllegalArgumentException("from can not less than 0 and maxSize must greater than 0");
            157 }
            158 Vector v = new Vector();
            159 RecordEnumeration ren = null;
            160 try {
            161 RecordStore rs = getRecordStore(cls.getName());
            162 ren = rs.enumerateRecords(null, null, false);
            163 fetchRecord(v, cls, ren, from, maxSize);
            164 } catch (Exception exe) {
            165 LogManager.error("RMSUtil.listObjects(),Class = " + cls + ",from = " + from + ",maxSize = " + maxSize + ",exe = " + exe);
            166 exe.printStackTrace();
            167 } finally {
            168 ren.destroy();
            169 }
            170 return v;
            171 }
            172
            173 /**
            174 * 用于前面一個方法和后面一個方法的共用方法,
            175 * 它用來從特定的記錄枚舉里面去取特定的記錄,
            176 * 并放到特定的地方
            177 * @param v 要保存的地方
            178 * @param cls 要實(shí)例化的類
            179 * @param ren 記錄的枚舉
            180 * @param from 從哪里開始取
            181 * @param maxSize 要取多少條記錄
            182 * @throws java.lang.Exception 可能會拋出的異常
            183 */
            184 private static void fetchRecord(Vector v, Class cls, RecordEnumeration ren, int from, int maxSize) throws Exception {
            185 int index = 0;
            186 int size = 0;
            187 while (ren.hasNextElement()) {
            188 int id = ren.nextRecordId();
            189 if (index >= from) {
            190 if (size < maxSize) {
            191 Serializable ser = readObject(id, cls);
            192 if (ser != null) {
            193 v.addElement(ser);
            194 size++;
            195 }
            196 } else {
            197 break;
            198 }
            199 }
            200 index++;
            201 }
            202 }
            203
            204 /**
            205 * 列出某個類的對象,并用一種過濾以及排序的方法來進(jìn)行過濾或者排序
            206 * @param cls 類名
            207 * @param fetcher 取記錄的方法
            208 * @return 記錄列表
            209 */
            210 public static Vector listObjects(Class cls, RecordFetcher fetcher) {
            211 System.out.println("fetcherfrom can not less than 0 and maxSize must greater than 0");
            216 }
            217 Vector v = new Vector();
            218 RecordEnumeration ren = null;
            219 try {
            220 RecordStore rs = getRecordStore(cls.getName());
            221 ren = rs.enumerateRecords(fetcher, fetcher, false);
            222 fetchRecord(v, cls, ren, from, maxSize);
            223 } catch (Exception exe) {
            224 LogManager.error("RMSUtil.listObjects(),Class = " + cls + ",exe = " + exe);
            225 exe.printStackTrace();
            226 } finally {
            227 ren.destroy();
            228 }
            229 return v;
            230 }
            231
            232 /**
            233 * 插入某個可延遲加載的對象的所有附件到數(shù)據(jù)庫里面去
            234 * 插入完成后,此lazy對象將變得很完整,因?yàn)榇藭r它的
            235 * 附件對象的ID都已經(jīng)設(shè)置好了
            236 * @param lazy 要插入附件的主對象
            237 * @return 是否插入成功
            238 */
            239 private static boolean insertAttachDatas(Lazy lazy) {
            240 try {
            241 Object[] attachKeys = lazy.getAttachKeys();
            242 RecordStore rs = getRecordStore(lazy.getNameOfAttachRMS());
            243 for (int i = 0; i < attachKeys.length; i++) {
            244 Object key = attachKeys[i];
            245 byte[] data = lazy.getAttach(key);
            246 int id = rs.addRecord(data, 0, data.length);
            247 lazy.savedAttach(key, id);
            248 }
            249 return true;
            250 } catch (Exception exe) {
            251 exe.printStackTrace();
            252 LogManager.error("RMSUtil.insertAttachDatas(),Lazy = " + lazy + ",exe = " + exe);
            253 return false;
            254 }
            255 }
            256
            257 /**
            258 * 得到某個可以延遲加載的對象的某個附件的字節(jié)數(shù)組內(nèi)容
            259 * TODO 如果能把此方法變成私有,那就更好了
            260 * 此方法是專門供lazy對象調(diào)用的,這樣的話,實(shí)體類里面就出現(xiàn)了
            261 * 讀取數(shù)據(jù)的方法,但是由于J2ME不支持反射,只能這樣實(shí)現(xiàn)了
            262 * @param lazy 可以延遲加載的對象
            263 * @param id 附件的ID
            264 * @return 對應(yīng)的數(shù)組
            265 */