boolean array / BitSet与String之间的转换

在安卓里,shared preferences只能储存简单类型(如int, boolean, string等)。其它的类型要么需要储存到数据库或其它缓存里,要么就要先转换成shared preferences所支持的类型。

这里我们将boolean array或BitSet储存在为String。然后在转换回来。

    public final static byte[] toByteArray(final BitSet bs) {
        final int bitsLength = bs.length();
        final int bytesLength = (bitsLength + 7) / 8;
        final byte[] bytes = new byte[bytesLength];
        int byteIdx;
        int bitIdx;
        for (int idx = bs.nextSetBit(0); idx >= 0; idx = bs.nextSetBit(idx + 1)) {
            byteIdx = bytesLength - idx / 8 - 1;
            bitIdx = idx % 8;
            bytes[byteIdx] |= 1 << bitIdx;
        }
        return bytes;
    }

    public final static BitSet fromByteArray(final byte[] bytes) {
        final int bitsLength = bytes.length * 8;
        final BitSet bs = new BitSet(bitsLength);
        for (int i = 0; i < bitsLength; i++) {
            if (((bytes[bytes.length - i / 8 - 1] >> (i % 8)) & 1) == 1) {
                bs.set(i);
            }
        }
        return bs;
    }

    public final static String toString(final BitSet bs) {
        return new String(toByteArray(bs), Charset.forName("ISO-8859-1"));
    }

    public final static BitSet fromString(final String data) {
        return fromByteArray(data.getBytes(Charset.forName("ISO-8859-1")));
    }

在Activity里面就很方便了:

    @Override
    protected void onPause() {
        super.onPause();
        getPreferences(Activity.MODE_PRIVATE).edit().putString("BITS", toString(this.bs)).commit();
    }

    @Override
    protected void onResume() {
        super.onResume();
        this.bs = fromString(getPreferences(Activity.MODE_PRIVATE).getString("BITS", ""));
    }

测试:

    static public void main(String[] args) throws IOException, AWTException, SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        BitSet bs = new BitSet();
        for (int i = 0; i < 1000; i++) {
            if (Math.random() < 0.5) {
                bs.set(i);
            }
        }

        String storedData = toString(bs);
        BitSet resumedData = fromString(storedData);
        System.out.println(resumedData.equals(bs));
    }

把boolean[]转换成BitSet:(boolean[] length必须另外存储进shared preferences里)
(注:推荐使用BitSet。在java里每个boolean都占用一个byte的位置。这样当boolean[]很大时,就很浪费内存了。在手机,平板电脑上内存可是很珍贵的。):

    public static final boolean[] fromBitSet(final BitSet bs, final int length) {
        final boolean[] b= new boolean[length];
        for (int idx = bs.nextSetBit(0); idx >= 0; idx = bs.nextSetBit(idx + 1)) {
            b[idx] = true;
        }
        return b;
    }

    public static final BitSet toBitSet(final boolean[] b) {
        final int l = b.length;
        final BitSet bs = new BitSet(l);
        for (int i = 0; i < l; i++) {
            if (b[i]) {
                bs.set(i);
            }
        }
        return bs;
    }
Advertisements