/** * read String pool, for apk binary xml file and resource table. * * @param in * @param stringPoolHeader * @return * @throws IOException */ public static StringPool readStringPool(TellableInputStream in, StringPoolHeader stringPoolHeader) throws IOException { long beginPos = in.tell(); long[] offsets = new long[(int) stringPoolHeader.stringCount]; // read strings offset if (stringPoolHeader.stringCount > 0) { for (int idx = 0; idx < stringPoolHeader.stringCount; idx++) { offsets[idx] = in.readUInt(); } } // read flag boolean sorted = (stringPoolHeader.flags & StringPoolHeader.SORTED_FLAG) != 0; StringEncoding stringEncoding = (stringPoolHeader.flags & StringPoolHeader.UTF8_FLAG) != 0 ? StringEncoding.UTF8 : StringEncoding.UTF16; // read strings. the head and metas have 28 bytes long stringPos = beginPos + stringPoolHeader.stringsStart - stringPoolHeader.headerSize; in.advanceIfNotRearch(stringPos); StringPoolEntry[] entries = new StringPoolEntry[offsets.length]; for (int i = 0; i < offsets.length; i++) { entries[i] = new StringPoolEntry(i, stringPos + offsets[i]); } Arrays.sort(entries); String lastStr = null; long lastOffset = -1; StringPool stringPool = new StringPool((int) stringPoolHeader.stringCount); for (StringPoolEntry entry : entries) { if (entry.getOffset() == lastOffset) { stringPool.set(entry.getIdx(), lastStr); continue; } in.advanceIfNotRearch(entry.getOffset()); lastOffset = entry.getOffset(); String str = ParseUtils.readString(in, stringEncoding); lastStr = str; stringPool.set(entry.getIdx(), str); } // read styles if (stringPoolHeader.styleCount > 0) { // now we just skip it } in.advanceIfNotRearch(beginPos + stringPoolHeader.chunkSize - stringPoolHeader.headerSize); return stringPool; }